Index: clang/include/clang/AST/Type.h =================================================================== --- clang/include/clang/AST/Type.h +++ clang/include/clang/AST/Type.h @@ -835,6 +835,10 @@ /// Returns true if it is not a class or if the class might not be dynamic. bool mayBeNotDynamicClass() const; + /// Returns true if this is a restrict pointer or contains a restrict pointer. + /// NOTE: A pointer to a restrict pointer does not count. + bool isRestrictOrContainsRestrictMembers() const; + // Don't promise in the API that anything besides 'const' can be // easily added. Index: clang/include/clang/Basic/CodeGenOptions.def =================================================================== --- clang/include/clang/Basic/CodeGenOptions.def +++ clang/include/clang/Basic/CodeGenOptions.def @@ -211,6 +211,8 @@ CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-path TBAA. +CODEGENOPT(FullRestrict , 1, 1) ///< Set when -ffull-restrict is enabled. +CODEGENOPT(NoNoAliasArgAttr , 1, 0) ///< Set when -fno-noalias-arguments is specified. CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection ///< in AddressSanitizer Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1524,6 +1524,19 @@ LangOpts<"RegisterStaticDestructors">, DefaultTrue, NegFlag, PosFlag>; +defm full_restrict : BoolFOption<"full-restrict", + CodeGenOpts<"FullRestrict">, DefaultTrue, + PosFlag, + NegFlag, + BothFlags<[CoreOption, CC1Option]>>; + +// Keep this behind an option - the alias analysis still works better +// with the noalias attribute on arguments. +defm fnoalias_arguments : BoolFOption<"noalias-arguments", + CodeGenOpts<"NoNoAliasArgAttr">, DefaultFalse, + NegFlag, + PosFlag, + BothFlags<[CoreOption]>>; def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group, Flags<[CC1Option]>, MarshallingInfoString>; Index: clang/lib/AST/Type.cpp =================================================================== --- clang/lib/AST/Type.cpp +++ clang/lib/AST/Type.cpp @@ -100,6 +100,26 @@ return !ClassDecl || ClassDecl->mayBeNonDynamicClass(); } +bool QualType::isRestrictOrContainsRestrictMembers() const { + if (isRestrictQualified()) { + return true; + } + + const Type *BaseElementType = getCanonicalType()->getBaseElementTypeUnsafe(); + assert(!isa(BaseElementType)); + + if (const RecordType *RecTy = dyn_cast(BaseElementType)) { + RecordDecl *RD = RecTy->getDecl(); + for (FieldDecl *FD : RD->fields()) { + if (FD->getType().isRestrictOrContainsRestrictMembers()) { + return true; + } + } + } + + return false; +} + bool QualType::isConstant(QualType T, const ASTContext &Ctx) { if (T.isConstQualified()) return true; Index: clang/lib/CodeGen/Address.h =================================================================== --- clang/lib/CodeGen/Address.h +++ clang/lib/CodeGen/Address.h @@ -39,6 +39,13 @@ return Pointer; } + /// Replace the current pointer of the addres with a new pointer. + void adaptPointer(llvm::Value *newPointer) { + assert(Pointer->getType() == newPointer->getType() && + "Address: changing the pointer must not change the type"); + Pointer = newPointer; + } + /// Return the type of the pointer value. llvm::PointerType *getType() const { return llvm::cast(getPointer()->getType()); Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -2806,7 +2806,10 @@ } // Set 'noalias' if an argument type has the `restrict` qualifier. - if (Arg->getType().isRestrictQualified()) + // For accurate full restrict support, we should not annotate arguments + // with noalias. The noalias atttribute is too strong. + if (Arg->getType().isRestrictQualified() && + (!CGM.getCodeGenOpts().NoNoAliasArgAttr)) AI->addAttr(llvm::Attribute::NoAlias); } @@ -4893,12 +4896,28 @@ ArgInfo.getDirectOffset() == 0) { assert(NumIRArgs == 1); llvm::Value *V; - if (!I->isAggregate()) + if (!I->isAggregate()) { V = I->getKnownRValue().getScalarVal(); - else - V = Builder.CreateLoad( - I->hasLValue() ? I->getKnownLValue().getAddress(*this) - : I->getKnownRValue().getAggregateAddress()); + } else { + Address Addr = I->hasLValue() + ? I->getKnownLValue().getAddress(*this) + : I->getKnownRValue().getAggregateAddress(); + if (I->getType().isRestrictOrContainsRestrictMembers() && + CGM.getCodeGenOpts().FullRestrict) { + // protect a load of an aggregate with restrict member pointers with + // an llvm.noalias.copy.guard. + // NOTE: also see CodeGenFunction::EmitAggregateCopy(); + auto NoAliasScopeMD = + getExistingOrUnknownNoAliasScope(Addr.getPointer()); + auto NoAliasDecl = getExistingNoAliasDeclOrNullptr(NoAliasScopeMD); + Addr.adaptPointer(Builder.CreateNoAliasCopyGuard( + Addr.getPointer(), NoAliasDecl, + CGM.getMDNoAliasOffsets(I->getType()), NoAliasScopeMD)); + } + llvm::LoadInst *LD = + Builder.CreateLoad(Addr, I->getType().isVolatileQualified()); + V = LD; + } // Implement swifterror by copying into a new swifterror argument. // We'll write back in the normal path out of the call. @@ -4980,6 +4999,22 @@ } else { // In the simple case, just pass the coerced loaded value. assert(NumIRArgs == 1); + if (Src.getElementType() == ArgInfo.getCoerceToType()) { + QualType Ty = I->getType(); + if (Ty.isRestrictOrContainsRestrictMembers() && + CGM.getCodeGenOpts().FullRestrict) { + // Protect a load of an aggregate with restrict member pointers with + // an llvm.noalias.copy.guard + // NOTE: also see CodeGenFunction::EmitAggregateCopy(); + auto NoAliasScopeMD = + getExistingOrUnknownNoAliasScope(Src.getPointer()); + auto NoAliasDecl = getExistingNoAliasDeclOrNullptr(NoAliasScopeMD); + Src.adaptPointer(Builder.CreateNoAliasCopyGuard( + Src.getPointer(), NoAliasDecl, + CGM.getMDNoAliasOffsets(I->getType()), NoAliasScopeMD)); + } + } + llvm::Value *Load = CreateCoercedLoad(Src, ArgInfo.getCoerceToType(), *this); Index: clang/lib/CodeGen/CGDecl.cpp =================================================================== --- clang/lib/CodeGen/CGDecl.cpp +++ clang/lib/CodeGen/CGDecl.cpp @@ -36,6 +36,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/MDBuilder.h" #include "llvm/IR/Type.h" using namespace clang; @@ -1315,6 +1316,7 @@ /// These turn into simple stack objects, or GlobalValues depending on target. void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) { AutoVarEmission emission = EmitAutoVarAlloca(D); + EmitAutoVarNoAlias(emission); EmitAutoVarInit(emission); EmitAutoVarCleanups(emission); } @@ -1912,6 +1914,126 @@ type.isVolatileQualified(), Builder, constant, /*IsAutoInit=*/false); } +// For all local restrict-qualified local variables, we create a noalias +// metadata scope. This scope is used to identify each restrict-qualified +// variable and the other memory accesses within the scope where its aliasing +// assumptions apply. The scope metadata is stored in the NoAliasAddrMap map +// where the pointer to the local variable is the key in the map. +// One variable can contain multiple restrict pointers. All of them are +// represented by a single scope. +void CodeGenFunction::EmitNoAliasDecl(const VarDecl &D, Address Loc) { + // Don't emit noalias intrinsics unless we're optimizing. + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + return; + + if (!CGM.getCodeGenOpts().FullRestrict) + return; + + QualType type = D.getType(); + + // Emit a noalias intrinsic for restrict-qualified variables. + if (!type.isRestrictOrContainsRestrictMembers()) + return; + + // Only emit a llvm.noalias.decl if the address is an alloca. + if (!isa(Loc.getPointer()->stripPointerCasts())) + return; + + // NOTE: keep in sync with (clang) CGDecl: getExistingOrUnknownNoAliasScope + // NOTE: keep in sync with (clang) CGDecl: EmitAutoVarNoAlias/EmitNoAliasDecl + // NOTE: keep in sync with (llvm) InlineFunction: CloneAliasScopeMetadata + llvm::MDBuilder MDB(CurFn->getContext()); + if (!NoAliasDomain) + NoAliasDomain = MDB.createAnonymousAliasScopeDomain(CurFn->getName()); + + std::string Name = (llvm::Twine(CurFn->getName()) + ": " + D.getName()).str(); + + llvm::MDNode *Scope = MDB.createAnonymousAliasScope(NoAliasDomain, Name); + addNoAliasScope(Scope); + + SmallVector ScopeListEntries(1, Scope); + llvm::MDNode *ScopeList = + llvm::MDNode::get(CurFn->getContext(), ScopeListEntries); + + NoAliasAddrMap[Loc.getPointer()] = ScopeList; + + if (HaveInsertPoint()) { + NoAliasDeclMap[ScopeList] = + Builder.CreateNoAliasDeclaration(Loc.getPointer(), ScopeList); + } +} + +llvm::MDNode * +CodeGenFunction::getExistingOrUnknownNoAliasScope(llvm::Value *Ptr) { + auto NAI = NoAliasAddrMap.find( + Ptr->stripInBoundsOffsets()); // make sure to find the base object + + if (NAI != NoAliasAddrMap.end()) { + return NAI->second; + } + if (!NoAliasUnknownScope) { + // NOTE: keep in sync with (clang) CGDecl:getExistingOrUnknownNoAliasScope + // NOTE: keep in sync with (clang) CGDecl:EmitAutoVarNoAlias/EmitNoAliasDecl + // NOTE: keep in sync with (llvm) InlineFunction:CloneAliasScopeMetadata + + // The unknown scope is used when we cannot yet pinpoint the exact scope. + llvm::MDBuilder MDB(CurFn->getContext()); + if (!NoAliasDomain) + NoAliasDomain = MDB.createAnonymousAliasScopeDomain(CurFn->getName()); + std::string Name = + (llvm::Twine(CurFn->getName()) + ": unknown scope").str(); + + llvm::MDNode *Scope = MDB.createAnonymousAliasScope(NoAliasDomain, Name); + FnNoAliasInfo.addNoAliasScope(Scope); // keep this at function level + + SmallVector ScopeListEntries(1, Scope); + NoAliasUnknownScope = + llvm::MDNode::get(CurFn->getContext(), ScopeListEntries); + CurFn->setMetadata("noalias", NoAliasUnknownScope); + } + + return NoAliasUnknownScope; +} + +llvm::Value * +CodeGenFunction::getExistingNoAliasDeclOrNullptr(llvm::MDNode *NoAliasScopeMD) { + llvm::Value *&NoAliasDecl = NoAliasDeclMap[NoAliasScopeMD]; + if (NoAliasDecl == nullptr) { + NoAliasDecl = llvm::ConstantPointerNull::get( + llvm::Type::getInt8PtrTy(getLLVMContext())); + } + return NoAliasDecl; +} + +void CodeGenFunction::EmitAutoVarNoAlias(const AutoVarEmission &emission) { + assert(emission.Variable && "emission was not valid!"); + + // Don't emit noalias intrinsics unless we're optimizing. + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + return; + + if (!CGM.getCodeGenOpts().FullRestrict) + return; + + const VarDecl &D = *emission.Variable; + + // Early exit: emission.getObjectAddress(..) can introduce extra code. + // Only do it if it is needed + if (!D.getType().isRestrictOrContainsRestrictMembers()) + return; + + // Check whether this is a byref variable that's potentially + // captured and moved by its own initializer. If so, we'll need to + // emit the initializer first, then copy into the variable. + const Expr *Init = D.getInit(); + bool capturedByInit = + Init && emission.IsEscapingByRef && isCapturedBy(D, Init); + + Address Loc = + capturedByInit ? emission.Addr : emission.getObjectAddress(*this); + EmitNoAliasDecl(D, Loc); +} + /// Emit an expression as an initializer for an object (variable, field, etc.) /// at the given location. The expression is not necessarily the normal /// initializer for the object, and the address is not necessarily @@ -2518,6 +2640,9 @@ llvm::Value *ArgVal = (DoStore ? Arg.getDirectValue() : nullptr); LValue lv = MakeAddrLValue(DeclPtr, Ty); + + EmitNoAliasDecl(D, DeclPtr); + if (IsScalar) { Qualifiers qs = Ty.getQualifiers(); if (Qualifiers::ObjCLifetime lt = qs.getObjCLifetime()) { Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -31,11 +31,13 @@ #include "clang/Basic/SourceManager.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/MatrixBuilder.h" +#include "llvm/IR/Metadata.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" @@ -1745,6 +1747,22 @@ if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); + // If this is a load from a restrict-qualified variable, then we have pointer + // aliasing assumptions that can be applied to the pointer value being loaded. + if (Ty.isRestrictQualified() && CGM.getCodeGenOpts().FullRestrict) { + auto NoAliasScopeMD = getExistingOrUnknownNoAliasScope(Addr.getPointer()); + auto NoAliasDecl = getExistingNoAliasDeclOrNullptr(NoAliasScopeMD); + auto *NoAliasLoad = Builder.CreateNoAliasPointer( + Load, NoAliasDecl, Addr.getPointer(), NoAliasScopeMD); + + // The llvm.noalias intrinsic can make use of the available alias info + NoAliasLoad->setAAMetadata(Load->getAAMetadata()); + + // ..as wel as the local restrict scope + // In both cases, this is about the 'P.addr'(getOperand(2) of llvm.noalias) + recordMemoryInstruction(NoAliasLoad); + return EmitFromMemory(NoAliasLoad, Ty); + } return EmitFromMemory(Load, Ty); } Index: clang/lib/CodeGen/CGExprAgg.cpp =================================================================== --- clang/lib/CodeGen/CGExprAgg.cpp +++ clang/lib/CodeGen/CGExprAgg.cpp @@ -2075,6 +2075,17 @@ } } + // Guard copies of structs containing restrict pointers + if (Ty.isRestrictOrContainsRestrictMembers() && + CGM.getCodeGenOpts().FullRestrict) { + // NOTE: also see CodeGenFunction::EmitCall() + auto NoAliasScopeMD = getExistingOrUnknownNoAliasScope(SrcPtr.getPointer()); + auto NoAliasDecl = getExistingNoAliasDeclOrNullptr(NoAliasScopeMD); + SrcPtr.adaptPointer(Builder.CreateNoAliasCopyGuard( + SrcPtr.getPointer(), NoAliasDecl, CGM.getMDNoAliasOffsets(Ty), + NoAliasScopeMD)); + } + if (getLangOpts().CUDAIsDevice) { if (Ty->isCUDADeviceBuiltinSurfaceType()) { if (getTargetHooks().emitCUDADeviceBuiltinSurfaceDeviceCopy(*this, Dest, @@ -2163,6 +2174,8 @@ } auto Inst = Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, isVolatile); + // track noalias scope for memcpy + recordMemoryInstruction(Inst); // Determine the metadata to describe the position of any padding in this // memcpy, as well as the TBAA tags for the members of the struct, in case Index: clang/lib/CodeGen/CGStmt.cpp =================================================================== --- clang/lib/CodeGen/CGStmt.cpp +++ clang/lib/CodeGen/CGStmt.cpp @@ -440,6 +440,28 @@ return true; } +bool CodeGenFunction::hasLocalRestrictVars(const CompoundStmt &S, + FunctionArgList *Args) { + // We may have restrict-qualified variables, but if we're not optimizing, we + // don't do anything special with them. + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + return false; + + if (Args) + for (const auto *VD : *Args) + if (VD->getType().isRestrictOrContainsRestrictMembers()) + return true; + + for (const auto *C : S.body()) + if (const auto *DS = dyn_cast(C)) + for (const auto *I : DS->decls()) + if (const auto *VD = dyn_cast(I)) + if (VD->getType().isRestrictOrContainsRestrictMembers()) + return true; + + return false; +} + /// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, /// this captures the expression result of the last sub-statement and returns it /// (for use by the statement expression extension). @@ -449,7 +471,7 @@ "LLVM IR generation of compound statement ('{}')"); // Keep track of the current cleanup stack depth, including debug scopes. - LexicalScope Scope(*this, S.getSourceRange()); + LexicalScope Scope(*this, S.getSourceRange(), hasLocalRestrictVars(S)); return EmitCompoundStmtWithoutScope(S, GetLast, AggSlot); } @@ -653,6 +675,24 @@ } } +// For all of the instructions generated for this lexical scope that access +// memory, add the noalias metadata associated with any block-local +// restrict-qualified pointers from this scope. +void CodeGenFunction::LexicalNoAliasInfo::addNoAliasMD() { + if (MemoryInsts.empty() || NoAliasScopes.empty()) + return; + + llvm::MDNode *NewScopeList = llvm::MDNode::get( + MemoryInsts[0]->getParent()->getContext(), NoAliasScopes); + + for (auto &I : MemoryInsts) + I->setMetadata( + llvm::LLVMContext::MD_noalias, + llvm::MDNode::concatenate(I->getMetadata(llvm::LLVMContext::MD_noalias), + NewScopeList)); + + MemoryInsts.clear(); +} void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) { EmitLabel(S.getDecl()); Index: clang/lib/CodeGen/CMakeLists.txt =================================================================== --- clang/lib/CodeGen/CMakeLists.txt +++ clang/lib/CodeGen/CMakeLists.txt @@ -69,6 +69,7 @@ CodeGenAction.cpp CodeGenFunction.cpp CodeGenModule.cpp + CodeGenNoAliasOffsets.cpp CodeGenPGO.cpp CodeGenTBAA.cpp CodeGenTypes.cpp Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -37,6 +37,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/Debug.h" @@ -317,8 +318,7 @@ /// CGBuilder insert helper. This function is called after an /// instruction is created using Builder. void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, - llvm::BasicBlock *BB, - llvm::BasicBlock::iterator InsertPt) const; + llvm::BasicBlock *BB, llvm::BasicBlock::iterator InsertPt); /// CurFuncDecl - Holds the Decl for the current outermost /// non-closure context. @@ -918,11 +918,54 @@ } }; + // Check if any local variable or argument contains a (direct) restrict + // pointer. + bool hasLocalRestrictVars(const CompoundStmt &S, + FunctionArgList *Args = nullptr); + + // Get the associated NoAliasScope for the Ptr (cast and geps will be + // stripped). If there is no associated scope returns the 'unknown function' + // scope. (which is created on demand) + llvm::MDNode *getExistingOrUnknownNoAliasScope(llvm::Value *Ptr); + + // Get the associated declaration + llvm::Value *getExistingNoAliasDeclOrNullptr(llvm::MDNode *NoAliasScopeMD); + + // The noalias scopes used to tag pointer values assigned to block-local + // restrict-qualified variables, and the memory-accessing instructions within + // this lexical scope to which the associated pointer-aliasing assumptions + // might apply. One of these will exist for each lexical scope. + struct LexicalNoAliasInfo { + bool RecordMemoryInsts; + llvm::TinyPtrVector MemoryInsts; + llvm::TinyPtrVector NoAliasScopes; + + LexicalNoAliasInfo(bool RecordMemoryInsts = false) + : RecordMemoryInsts(RecordMemoryInsts) {} + + void recordMemoryInsts() { RecordMemoryInsts = true; } + + void recordMemoryInstruction(llvm::Instruction *I) { + if (RecordMemoryInsts) + MemoryInsts.push_back(I); + } + + void addNoAliasScope(llvm::MDNode *Scope) { + assert(RecordMemoryInsts && + "Adding noalias scope but not recording memory accesses!"); + NoAliasScopes.push_back(Scope); + } + + void addNoAliasMD(); + }; + + LexicalNoAliasInfo FnNoAliasInfo; + // Cleanup stack depth of the RunCleanupsScope that was pushed most recently. EHScopeStack::stable_iterator CurrentCleanupScopeDepth = EHScopeStack::stable_end(); - class LexicalScope : public RunCleanupsScope { + class LexicalScope : public RunCleanupsScope, public LexicalNoAliasInfo { SourceRange Range; SmallVector Labels; LexicalScope *ParentScope; @@ -932,8 +975,10 @@ public: /// Enter a new cleanup scope. - explicit LexicalScope(CodeGenFunction &CGF, SourceRange Range) - : RunCleanupsScope(CGF), Range(Range), ParentScope(CGF.CurLexicalScope) { + explicit LexicalScope(CodeGenFunction &CGF, SourceRange Range, + bool RecordMemoryInsts = false) + : RunCleanupsScope(CGF), LexicalNoAliasInfo(RecordMemoryInsts), + Range(Range), ParentScope(CGF.CurLexicalScope) { CGF.CurLexicalScope = this; if (CGDebugInfo *DI = CGF.getDebugInfo()) DI->EmitLexicalBlockStart(CGF.Builder, Range.getBegin()); @@ -944,6 +989,19 @@ Labels.push_back(label); } + // If we have block-local restrict-qualified pointers, we need to keep + // track of the memory-accessing instructions in the blocks where such + // pointers are declared (including lexical scopes that are children of + // those blocks) so that we can later add the appropriate metadata. Record + // this instruction and so the same in any parent scopes. + void recordMemoryInstruction(llvm::Instruction *I) { + LexicalNoAliasInfo::recordMemoryInstruction(I); + if (ParentScope) + ParentScope->recordMemoryInstruction(I); + else + CGF.FnNoAliasInfo.recordMemoryInstruction(I); + } + /// Exit this cleanup scope, emitting any accumulated /// cleanups. ~LexicalScope() { @@ -961,6 +1019,8 @@ /// Force the emission of cleanups now, instead of waiting /// until this object is destroyed. void ForceCleanup() { + addNoAliasMD(); + CGF.CurLexicalScope = ParentScope; RunCleanupsScope::ForceCleanup(); @@ -977,6 +1037,23 @@ typedef llvm::DenseMap DeclMapTy; + // Record this instruction for the purpose of later adding noalias metadata, + // is applicible, in order to support block-local restrict-qualified + // pointers. + void recordMemoryInstruction(llvm::Instruction *I) { + if (CurLexicalScope) + CurLexicalScope->recordMemoryInstruction(I); + else + FnNoAliasInfo.recordMemoryInstruction(I); + } + + void addNoAliasScope(llvm::MDNode *Scope) { + if (CurLexicalScope) + CurLexicalScope->addNoAliasScope(Scope); + else + FnNoAliasInfo.addNoAliasScope(Scope); + } + /// The class used to assign some variables some temporarily addresses. class OMPMapVars { DeclMapTy SavedLocals; @@ -1967,6 +2044,19 @@ void EmitOpenCLKernelMetadata(const FunctionDecl *FD, llvm::Function *Fn); + /// The noalias domain metadata for this function. + llvm::MDNode *NoAliasDomain = nullptr; + + /// A map between the addresses of local restrict-qualified variables and + /// their noalias scope. + llvm::DenseMap NoAliasAddrMap; + + /// A map between the noalias scope and its declaration + llvm::DenseMap NoAliasDeclMap; + + /// The node representing 'out-of-function' scope + llvm::MDNode *NoAliasUnknownScope = nullptr; + public: CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext=false); ~CodeGenFunction(); @@ -3114,6 +3204,9 @@ void emitAutoVarTypeCleanup(const AutoVarEmission &emission, QualType::DestructionKind dtorKind); + void EmitNoAliasDecl(const VarDecl &D, Address Loc); + void EmitAutoVarNoAlias(const AutoVarEmission &emission); + /// Emits the alloca and debug information for the size expressions for each /// dimension of an array. It registers the association of its (1-dimensional) /// QualTypes and size expression's debug node, so that CGDebugInfo can Index: clang/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenFunction.cpp +++ clang/lib/CodeGen/CodeGenFunction.cpp @@ -726,6 +726,11 @@ CurFn = Fn; CurFnInfo = &FnInfo; assert(CurFn->isDeclaration() && "Function already has body?"); + NoAliasUnknownScope = nullptr; // make sure we start without a function scope + + // Always track memory instructions. When a restrict usage is encountered, + // they will be annotated with the necessary scopes. + FnNoAliasInfo.recordMemoryInsts(); // If this function is ignored for any of the enabled sanitizers, // disable the sanitizer for the function. @@ -1204,10 +1209,15 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { incrementProfileCounter(Body); - if (const CompoundStmt *S = dyn_cast(Body)) + if (const CompoundStmt *S = dyn_cast(Body)) { EmitCompoundStmtWithoutScope(*S); - else + + // Now that we're done with the block, add noalias metadata if we had any + // block-local restrict-qualified pointers. + FnNoAliasInfo.addNoAliasMD(); + } else { EmitStmt(Body); + } // This is checked after emitting the function body so we know if there // are any permitted infinite loops. @@ -2482,10 +2492,18 @@ void CodeGenFunction::InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB, - llvm::BasicBlock::iterator InsertPt) const { + llvm::BasicBlock::iterator InsertPt) { LoopStack.InsertHelper(I); if (IsSanitizerScope) CGM.getSanitizerMetadata()->disableSanitizerForInstruction(I); + + // When we have block-local restrict-qualified pointers, we need to record + // all memory-accessing instructions (i.e. any kind of instruction for which + // AA::getModRefInfo might return something other than NoModRef) so that they + // can be tagged with noalias metadata with noalias scopes corresponding to + // the applicable restrict-qualified pointers. + if (I->mayReadOrWriteMemory()) + recordMemoryInstruction(I); } void CGBuilderInserter::InsertHelper( Index: clang/lib/CodeGen/CodeGenModule.h =================================================================== --- clang/lib/CodeGen/CodeGenModule.h +++ clang/lib/CodeGen/CodeGenModule.h @@ -87,6 +87,7 @@ class CallArgList; class CodeGenFunction; class CodeGenTBAA; +class CodeGenNoAliasOffsets; class CGCXXABI; class CGDebugInfo; class CGObjCRuntime; @@ -314,6 +315,7 @@ std::string ModuleNameHash = ""; std::unique_ptr TBAA; + std::unique_ptr NoAliasOffsets; mutable std::unique_ptr TheTargetCodeGenInfo; @@ -782,6 +784,10 @@ return getTBAAAccessInfo(AccessType); } + /// Returns NoAliasOffsets metadata. + /// If no valid noalias pointer offsets are found, returns nullptr; + llvm::MDNode *getMDNoAliasOffsets(QualType QTy); + bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); bool isPaddedAtomicType(QualType type); Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -21,6 +21,7 @@ #include "CGOpenMPRuntime.h" #include "CGOpenMPRuntimeGPU.h" #include "CodeGenFunction.h" +#include "CodeGenNoAliasOffsets.h" #include "CodeGenPGO.h" #include "ConstantEmitter.h" #include "CoverageMappingGen.h" @@ -152,6 +153,8 @@ TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(), getCXXABI().getMangleContext())); + NoAliasOffsets = std::make_unique(Context, TheModule); + // If debug info or coverage generation is enabled, create the CGDebugInfo // object. if (CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo || @@ -964,6 +967,10 @@ return TBAA->mergeTBAAInfoForConditionalOperator(DestInfo, SrcInfo); } +llvm::MDNode *CodeGenModule::getMDNoAliasOffsets(QualType QTy) { + return NoAliasOffsets->getMDNoAliasOffsets(QTy); +} + void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst, TBAAAccessInfo TBAAInfo) { if (llvm::MDNode *Tag = getTBAAAccessTagInfo(TBAAInfo)) Index: clang/lib/CodeGen/CodeGenNoAliasOffsets.h =================================================================== --- /dev/null +++ clang/lib/CodeGen/CodeGenNoAliasOffsets.h @@ -0,0 +1,53 @@ +//===--- CodeGenNoAliasOffsets.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 +// +//===----------------------------------------------------------------------===// +// +// This class manages the NoAlias Copyguard offset information, that tracks the +// locations of noalias (restrict) pointers in a struct. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENNOALIASOFFSETS_H +#define LLVM_CLANG_LIB_CODEGEN_CODEGENNOALIASOFFSETS_H + +#include "clang/AST/Type.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Metadata.h" + +namespace clang { +class ASTContext; + +namespace CodeGen { +/// CodeGenNoAliasOffsets - This class organizes the cross-module state that is +/// used while lowering AST types to LLVM types. +class CodeGenNoAliasOffsets { + ASTContext &Context; + + // MDHelper - Helper for creating metadata. + llvm::MDBuilder MDHelper; + + using Key = llvm::PointerIntPair; + /// NoAliasOffsetsMetadataCache - This maps clang::Types to llvm::MDNodes + /// describing them for struct assignments. + llvm::DenseMap NoAliasOffsetsMetadataCache; + +public: + CodeGenNoAliasOffsets(ASTContext &Ctx, llvm::Module &M); + ~CodeGenNoAliasOffsets(); + + /// getMDNoAliasOffsets - Get metadata used to describe the locations of + /// restrict pointers in structs/unions/arrays. + llvm::MDNode *getMDNoAliasOffsets(QualType QTy); + llvm::MDNode *getMDNoAliasOffsets(const Type *Ty, bool IsRestrict); +}; + +} // end namespace CodeGen +} // end namespace clang +#endif Index: clang/lib/CodeGen/CodeGenNoAliasOffsets.cpp =================================================================== --- /dev/null +++ clang/lib/CodeGen/CodeGenNoAliasOffsets.cpp @@ -0,0 +1,118 @@ +//===--- CodeGenNoAliasOffsets.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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This class manages the NoAlias Copyguard offset information, that tracks the +// locations of noalias (restrict) pointers in a struct. +// +//===----------------------------------------------------------------------===// + +#include "CodeGenNoAliasOffsets.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" +#include "clang/AST/Mangle.h" +#include "clang/AST/RecordLayout.h" +#include "clang/Basic/CodeGenOptions.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +#define DEBUG_TYPE "CodeGenNoAliasOffsets" +using namespace clang; +using namespace CodeGen; + +using NoAliasOffsetsField = llvm::MDBuilder::NoAliasOffsetsField; + +class NoAliasOffsets { +public: + NoAliasOffsets(int64_t GlobalSize) : GlobalSize(GlobalSize) {} + + void add(NoAliasOffsetsField Rhs); + bool empty() const { return Items.empty(); } + + int64_t GlobalSize = 0; + SmallVector Items; +}; + +void NoAliasOffsets::add(NoAliasOffsetsField Rhs) { + if (!Rhs.isValid()) + return; + + // Try to simplify the dependency. + while (Rhs.tryPullUp()) + ; + + // Now, let's try to merge the new field with the last available field. + if (!Items.empty()) + if (Items.back().tryMerge(Rhs)) + return; + + Items.push_back(Rhs); +} + +CodeGenNoAliasOffsets::CodeGenNoAliasOffsets(ASTContext &Ctx, llvm::Module &M) + : Context(Ctx), MDHelper(M.getContext()) {} + +CodeGenNoAliasOffsets::~CodeGenNoAliasOffsets() {} + +llvm::MDNode *CodeGenNoAliasOffsets::getMDNoAliasOffsets(QualType QTy) { + return getMDNoAliasOffsets(Context.getCanonicalType(QTy).getTypePtr(), + QTy.isRestrictQualified()); +} + +llvm::MDNode *CodeGenNoAliasOffsets::getMDNoAliasOffsets(const Type *Ty, + bool IsRestrict) { + Key K(Ty, IsRestrict); + //@ FIXME: should we check the cache after handling the restrict ? + // Or should we add the restrict bool ? + { + auto It = NoAliasOffsetsMetadataCache.find(K); + if (It != NoAliasOffsetsMetadataCache.end()) { + return It->second; + } + } + + int64_t Size = Context.getTypeSizeInChars(Ty).getQuantity(); + NoAliasOffsets TheOffsets(Size); + + if (const auto *RecTy = Ty->getAs()) { + RecordDecl *RD = RecTy->getDecl(); + const ASTRecordLayout &ARL = Context.getASTRecordLayout(RD); + + // FIXME: should we recurse into all structures or only those that + // contain restrict ? + for (FieldDecl *FD : RD->fields()) { + auto FieldDelta = ARL.getFieldOffset(FD->getFieldIndex()) / 8; + TheOffsets.add(NoAliasOffsetsField( + FieldDelta, getMDNoAliasOffsets(FD->getType()), 1)); + } + } else if (isa(Ty)) { + if (IsRestrict) { + int64_t PtrSize = Context.getTypeSizeInChars(Ty).getQuantity(); + TheOffsets.add(NoAliasOffsetsField(0, PtrSize, 1)); + } + } else if (auto *ATy = dyn_cast(Ty)) { + int64_t Count = 0; // Unbounded array + if (auto CATy = dyn_cast(Ty)) + Count = CATy->getSize().getSExtValue(); // 0 means unbounded + + auto *ElemTy = ATy->getElementType().getCanonicalType().getTypePtr(); + TheOffsets.add( + NoAliasOffsetsField(0, getMDNoAliasOffsets(ElemTy, IsRestrict), Count)); + } else { + // not something we are interested in + } + + auto *MD = + MDHelper.createNoAliasOffsets(TheOffsets.GlobalSize, TheOffsets.Items); + return NoAliasOffsetsMetadataCache[K] = MD; +} Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -4918,6 +4918,18 @@ options::OPT_fdelete_null_pointer_checks, false)) CmdArgs.push_back("-fno-delete-null-pointer-checks"); + if (Arg *FullRestrictArg = Args.getLastArg(options::OPT_ffull_restrict, + options::OPT_fno_full_restrict)) { + if (FullRestrictArg->getOption().matches(options::OPT_fno_full_restrict)) { + // Disable noalias intrinsic support for noalias attribute on arguments + CmdArgs.push_back("-fno-full-restrict"); + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-use-noalias-intrinsic-during-inlining=scopes"); + } else { + CmdArgs.push_back("-ffull-restrict"); + } + } + // LLVM Code Generator Options. for (const Arg *A : Args.filtered(options::OPT_frewrite_map_file_EQ)) { Index: clang/test/CodeGen/aarch64-ls64.c =================================================================== --- clang/test/CodeGen/aarch64-ls64.c +++ clang/test/CodeGen/aarch64-ls64.c @@ -19,38 +19,39 @@ // CHECK-LABEL: @test_ld64b( // CHECK-NEXT: entry: // CHECK-NEXT: [[__ADDR_ADDR_I:%.*]] = alloca i8*, align 8 -// CHECK-NEXT: [[REF_TMP:%.*]] = alloca [[STRUCT_DATA512_T:%.*]], align 8 +// CHECK-NEXT: [[REF_TMP_ALLOC:%.*]] = alloca [[STRUCT_DATA512_T:%.*]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i8*, i8** @addr, align 8 -// CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !6) +// CHECK-NEXT: [[TMP_DECL:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.data512_ts.i64(%struct.data512_t** null, i64 0, metadata !6) +// CHECK-NEXT: [[REF_TMP:%.*]] = call %struct.data512_t* @llvm.noalias.p0s_struct.data512_ts.p0i8.p0p0s_struct.data512_ts.i64(%struct.data512_t* [[REF_TMP_ALLOC]], i8* [[TMP_DECL]], %struct.data512_t** null, i64 0, metadata !6), !noalias !6 // CHECK-NEXT: store i8* [[TMP0]], i8** [[__ADDR_ADDR_I]], align 8, !noalias !6 // CHECK-NEXT: [[TMP1:%.*]] = load i8*, i8** [[__ADDR_ADDR_I]], align 8, !noalias !6 // CHECK-NEXT: [[VAL_I:%.*]] = getelementptr inbounds [[STRUCT_DATA512_T]], %struct.data512_t* [[REF_TMP]], i32 0, i32 0 // CHECK-NEXT: [[ARRAYDECAY_I:%.*]] = getelementptr inbounds [8 x i64], [8 x i64]* [[VAL_I]], i64 0, i64 0 // CHECK-NEXT: [[TMP2:%.*]] = call { i64, i64, i64, i64, i64, i64, i64, i64 } @llvm.aarch64.ld64b(i8* [[TMP1]]) [[ATTR2:#.*]], !noalias !6 // CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64 } [[TMP2]], 0 -// CHECK-NEXT: store i64 [[TMP3]], i64* [[ARRAYDECAY_I]], align 8, !alias.scope !6 +// CHECK-NEXT: store i64 [[TMP3]], i64* [[ARRAYDECAY_I]], align 8, !noalias !6 // CHECK-NEXT: [[TMP4:%.*]] = getelementptr i64, i64* [[ARRAYDECAY_I]], i32 1 // CHECK-NEXT: [[TMP5:%.*]] = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64 } [[TMP2]], 1 -// CHECK-NEXT: store i64 [[TMP5]], i64* [[TMP4]], align 8, !alias.scope !6 +// CHECK-NEXT: store i64 [[TMP5]], i64* [[TMP4]], align 8, !noalias !6 // CHECK-NEXT: [[TMP6:%.*]] = getelementptr i64, i64* [[ARRAYDECAY_I]], i32 2 // CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64 } [[TMP2]], 2 -// CHECK-NEXT: store i64 [[TMP7]], i64* [[TMP6]], align 8, !alias.scope !6 +// CHECK-NEXT: store i64 [[TMP7]], i64* [[TMP6]], align 8, !noalias !6 // CHECK-NEXT: [[TMP8:%.*]] = getelementptr i64, i64* [[ARRAYDECAY_I]], i32 3 // CHECK-NEXT: [[TMP9:%.*]] = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64 } [[TMP2]], 3 -// CHECK-NEXT: store i64 [[TMP9]], i64* [[TMP8]], align 8, !alias.scope !6 +// CHECK-NEXT: store i64 [[TMP9]], i64* [[TMP8]], align 8, !noalias !6 // CHECK-NEXT: [[TMP10:%.*]] = getelementptr i64, i64* [[ARRAYDECAY_I]], i32 4 // CHECK-NEXT: [[TMP11:%.*]] = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64 } [[TMP2]], 4 -// CHECK-NEXT: store i64 [[TMP11]], i64* [[TMP10]], align 8, !alias.scope !6 +// CHECK-NEXT: store i64 [[TMP11]], i64* [[TMP10]], align 8, !noalias !6 // CHECK-NEXT: [[TMP12:%.*]] = getelementptr i64, i64* [[ARRAYDECAY_I]], i32 5 // CHECK-NEXT: [[TMP13:%.*]] = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64 } [[TMP2]], 5 -// CHECK-NEXT: store i64 [[TMP13]], i64* [[TMP12]], align 8, !alias.scope !6 +// CHECK-NEXT: store i64 [[TMP13]], i64* [[TMP12]], align 8, !noalias !6 // CHECK-NEXT: [[TMP14:%.*]] = getelementptr i64, i64* [[ARRAYDECAY_I]], i32 6 // CHECK-NEXT: [[TMP15:%.*]] = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64 } [[TMP2]], 6 -// CHECK-NEXT: store i64 [[TMP15]], i64* [[TMP14]], align 8, !alias.scope !6 +// CHECK-NEXT: store i64 [[TMP15]], i64* [[TMP14]], align 8, !noalias !6 // CHECK-NEXT: [[TMP16:%.*]] = getelementptr i64, i64* [[ARRAYDECAY_I]], i32 7 // CHECK-NEXT: [[TMP17:%.*]] = extractvalue { i64, i64, i64, i64, i64, i64, i64, i64 } [[TMP2]], 7 -// CHECK-NEXT: store i64 [[TMP17]], i64* [[TMP16]], align 8, !alias.scope !6 -// CHECK-NEXT: [[TMP18:%.*]] = bitcast %struct.data512_t* [[REF_TMP]] to i8* +// CHECK-NEXT: store i64 [[TMP17]], i64* [[TMP16]], align 8, !noalias !6 +// CHECK-NEXT: [[TMP18:%.*]] = bitcast %struct.data512_t* [[REF_TMP_ALLOC]] to i8* // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 bitcast (%struct.data512_t* @val to i8*), i8* align 8 [[TMP18]], i64 64, i1 false) // CHECK-NEXT: ret void // Index: clang/test/CodeGen/arm_neon_intrinsics.c =================================================================== --- clang/test/CodeGen/arm_neon_intrinsics.c +++ clang/test/CodeGen/arm_neon_intrinsics.c @@ -2,6 +2,7 @@ // RUN: -target-cpu swift -fallow-half-arguments-and-returns \ // RUN: -target-feature +fullfp16 -ffreestanding \ // RUN: -flax-vector-conversions=none \ +// RUN: -mllvm --use-noalias-intrinsic-during-inlining=scopes \ // RUN: -disable-O0-optnone -emit-llvm -o - %s \ // RUN: | opt -S -mem2reg | FileCheck %s Index: clang/test/CodeGen/restrict/arg_reuse.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/arg_reuse.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict -fno-noalias-arguments %s -emit-llvm -o - | FileCheck %s + +// NOTE: use -no-noalias-arguments to block mapping restrict arguments on the 'noalias +// attribute which is too strong for restrict + +// A number of testcases from our wiki (2018/6/7_llvm_restrict_examples +// As llvm/clang treat __restrict differently in following cases: +int test_arg_restrict_vs_local_restrict_01(int *__restrict pA, int *pB, int *pC) { + int *tmp = pA; + *tmp = 42; + pA = pB; + *pA = 43; + *pC = 99; + return *tmp; // fail: needs a load !!! (either 42 or 43) +} + +// CHECK: @test_arg_restrict_vs_local_restrict_01 +// CHECK-NOT: ret i32 42 +// CHECK-NOT: ret i32 43 +// CHECK-NOT: ret i32 99 + +int test_arg_restrict_vs_local_restrict_02(int *pA_, int *pB, int *pC) { + int *__restrict pA; + pA = pA_; + int *tmp = pA; + *tmp = 42; + pA = pB; + *pA = 43; + *pC = 99; + return *tmp; // needs a load !!! (either 42 or 43) +} + +// CHECK: @test_arg_restrict_vs_local_restrict_02 +// CHECK-NOT: ret i32 42 +// CHECK-NOT: ret i32 43 +// CHECK-NOT: ret i32 99 Index: clang/test/CodeGen/restrict/array.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/array.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +int r; +void ex1(int *); + +void test_FOO_local(int *pA, int *pB, int *pC) { + int *restrict tmp[3] = {pA, pB, pC}; + *tmp[0] = 42; + *tmp[1] = 43; +} + +// CHECK-LABEL: void @test_FOO_local( +// CHECK: [[tmp:%.*]] = alloca [3 x i32*], align 16 +// CHECK: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0a3p0i32.i64([3 x i32*]* [[tmp]], i64 0, metadata [[TAG_6:!.*]]) +// CHECK: [[arrayidx_begin:%.*]] = getelementptr inbounds [3 x i32*], [3 x i32*]* [[tmp]], i64 0, i64 0 +// CHECK: [[arrayidx:%.*]] = getelementptr inbounds [3 x i32*], [3 x i32*]* [[tmp]], i64 0, i64 0 +// CHECK: [[TMP5:%.*]] = load i32*, i32** [[arrayidx]], align 16, !tbaa [[TAG_2:!.*]], !noalias [[TAG_6]] +// CHECK: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP1]], i32** [[arrayidx]], i64 0, metadata [[TAG_6]]), !tbaa [[TAG_2]], !noalias [[TAG_6]] +// CHECK: store i32 42, i32* [[TMP6]], align 4, !tbaa [[TAG_9:!.*]], !noalias [[TAG_6]] +// CHECK: [[arrayidx2:%.*]] = getelementptr inbounds [3 x i32*], [3 x i32*]* [[tmp]], i64 0, i64 1 +// CHECK: [[TMP7:%.*]] = load i32*, i32** [[arrayidx2]], align 8, !tbaa [[TAG_2]], !noalias [[TAG_6]] +// CHECK: [[TMP8:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP7]], i8* [[TMP1]], i32** [[arrayidx2]], i64 0, metadata [[TAG_6]]), !tbaa [[TAG_2]], !noalias [[TAG_6]] +// CHECK: store i32 43, i32* [[TMP8]], align 4, !tbaa [[TAG_9]], !noalias [[TAG_6]] +// CHECK: ret void + +void test_FOO_p(int *restrict p) { + *p = 42; +} + +// define void @test_FOO_p(i32* noalias %p) #0 { +// CHECK-LABEL: void @test_FOO_p( +// CHECK: [[p_addr:%.*]] = alloca i32*, align 8 +// CHECK-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[p_addr]], i64 0, metadata [[TAG_11:!.*]]) +// CHECK-NEXT: store i32* [[p:%.*]], i32** [[p_addr]], align 8, !tbaa [[TAG_2:!.*]], !noalias [[TAG_11]] +// CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** [[p_addr]], align 8, !tbaa [[TAG_2]], !noalias [[TAG_11]] +// CHECK-NEXT: [[TMP2:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP1]], i8* [[TMP0]], i32** [[p_addr]], i64 0, metadata [[TAG_11]]), !tbaa [[TAG_2]], !noalias [[TAG_11]] +// CHECK-NEXT: store i32 42, i32* [[TMP2]], align 4, !tbaa [[TAG_9:!.*]], !noalias [[TAG_11]] +// CHECK-NEXT: ret void + +void test_FOO_pp(int *restrict *p) { + *p[0] = 42; +} + +// define void @test_FOO_pp(i32** %p) #0 !noalias !14 { +// CHECK: void @test_FOO_pp(i32** [[p:%.*]]) #0 !noalias [[TAG_14:!.*]] { +// CHECK: [[p_addr:%.*]] = alloca i32**, align 8 +// CHECK-NEXT: store i32** [[p]], i32*** [[p_addr]], align 8, !tbaa [[TAG_2:!.*]], !noalias [[TAG_14:!.*]] +// CHECK-NEXT: [[TMP0:%.*]] = load i32**, i32*** [[p_addr]], align 8, !tbaa [[TAG_2]], !noalias [[TAG_14]] +// CHECK-NEXT: [[arrayidx:%.*]] = getelementptr inbounds i32*, i32** [[TMP0]], i64 0 +// CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** [[arrayidx]], align 8, !tbaa [[TAG_2]], !noalias [[TAG_14]] +// CHECK-NEXT: [[TMP2:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP1]], i8* null, i32** [[arrayidx]], i64 0, metadata [[TAG_14]]), !tbaa [[TAG_2]], !noalias [[TAG_14]] +// CHECK-NEXT: store i32 42, i32* [[TMP2]], align 4, !tbaa [[TAG_9:!.*]], !noalias [[TAG_14]] +// CHECK-NEXT: ret void Index: clang/test/CodeGen/restrict/basic.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/basic.c @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +int r; +void ex1(int *); + +int *a; +int *foo() { + int *restrict x = a; + return x; + + // CHECK-LABEL: i32* @foo( + // CHECK: [[x:%.*]] = alloca i32*, align 8 + // CHECK: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[x]], i64 0, metadata [[TAG_2:!.*]]) + // CHECK: [[TMP3:%.*]] = load i32*, i32** [[x]], align 8, !tbaa !5, !noalias [[TAG_2]] + // CHECK: [[TMP4:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP3]], i8* [[TMP1]], i32** [[x]], i64 0, metadata !2), !tbaa !5, !noalias [[TAG_2]] + // CHECK: ret i32* [[TMP4]] +} + +int *a2; +int *foo1(int b) { + int *restrict x; + + // CHECK-LABEL: define i32* @foo1(i32 + // CHECK: [[b_addr:%.*]] = alloca i32, align 4 + // CHECK: [[x:%.*]] = alloca i32*, align 8 + // CHECK: [[x2:%.*]] = alloca i32*, align 8 + // CHECK: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[x]], i64 0, metadata [[TAG_x:!.*]]) + + if (b) { + x = a; + r += *x; + ex1(x); + + // CHECK: [[TMP3:%.*]] = load i32*, i32** @a, align 8, !tbaa [[TAG_5:!.*]], !noalias [[TAG_x_x2:!.*]] + // CHECK: store i32* [[TMP3]], i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + + // CHECK: [[TMP4:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP5:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP4]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP6:%.*]] = load i32, i32* [[TMP5]], align 4, !tbaa [[TAG_9:!.*]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP7:%.*]] = load i32, i32* @r, align 4, !tbaa [[TAG_9]], !noalias [[TAG_x_x2]] + // CHECK: [[add:%.*]] = add nsw i32 [[TMP7]], [[TMP6]] + // CHECK: store i32 [[add]], i32* @r, align 4, !tbaa [[TAG_9]], !noalias [[TAG_x_x2]] + + // CHECK: [[TMP8:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP9:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP8]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: call void @ex1(i32* [[TMP9]]), !noalias [[TAG_x_x2]] + + ++x; + *x = r; + ex1(x); + + // CHECK: [[TMP10:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP10]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[incdec_ptr:%.*]] = getelementptr inbounds i32, i32* [[TMP11]], i32 1 + // CHECK: store i32* [[incdec_ptr]], i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + + // CHECK: [[TMP12:%.*]] = load i32, i32* @r, align 4, !tbaa [[TAG_9]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP13:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP14:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP13]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: store i32 [[TMP12]], i32* [[TMP14]], align 4, !tbaa [[TAG_9]], !noalias [[TAG_x_x2]] + + // CHECK: [[TMP15:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP16:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP15]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: call void @ex1(i32* [[TMP16]]), !noalias [[TAG_x_x2]] + + x += b; + *x = r; + ex1(x); + + // CHECK: [[TMP17:%.*]] = load i32, i32* [[b_addr]], align 4, !tbaa [[TAG_9]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP18:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP19:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP18]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[idx_ext:%.*]] = sext i32 [[TMP17]] to i64 + // CHECK: [[add_ptr:%.*]] = getelementptr inbounds i32, i32* [[TMP19]], i64 [[idx_ext]] + // CHECK: store i32* [[add_ptr]], i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + + // CHECK: [[TMP20:%.*]] = load i32, i32* @r, align 4, !tbaa [[TAG_9]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP21:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP22:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP21]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: store i32 [[TMP20]], i32* [[TMP22]], align 4, !tbaa [[TAG_9]], !noalias [[TAG_x_x2]] + + // CHECK: [[TMP23:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP24:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP23]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: call void @ex1(i32* [[TMP24]]), !noalias [[TAG_x_x2]] + + int *restrict x2 = a2; + *x2 = r; + ex1(x2); + + // CHECK: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[x2]], i64 0, metadata [[TAG_x2:!.*]]) + // CHECK: [[TMP27:%.*]] = load i32*, i32** @a2, align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: store i32* [[TMP27]], i32** [[x2]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + + // CHECK: [[TMP28:%.*]] = load i32, i32* @r, align 4, !tbaa [[TAG_9]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP29:%.*]] = load i32*, i32** [[x2]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP30:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP29]], i8* [[TMP26]], i32** [[x2]], i64 0, metadata [[TAG_x2]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: store i32 [[TMP28]], i32* [[TMP30]], align 4, !tbaa [[TAG_9]], !noalias [[TAG_x_x2]] + + // CHECK: [[TMP31:%.*]] = load i32*, i32** [[x2]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: [[TMP32:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP31]], i8* [[TMP26]], i32** [[x2]], i64 0, metadata [[TAG_x2]]), !tbaa [[TAG_5]], !noalias [[TAG_x_x2]] + // CHECK: call void @ex1(i32* [[TMP32]]), !noalias [[TAG_x_x2]] + } else { + x = a2; + r += *x; + // CHECK: [[TMP34:%.*]] = load i32*, i32** @a2, align 8, !tbaa [[TAG_5]], !noalias [[TAG_x]] + // CHECK: store i32* [[TMP34]], i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x]] + + // CHECK: [[TMP35:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x]] + // CHECK: [[TMP36:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP35]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x]] + // CHECK: [[TMP37:%.*]] = load i32, i32* [[TMP36]], align 4, !tbaa [[TAG_9]], !noalias [[TAG_x]] + // CHECK: [[TMP38:%.*]] = load i32, i32* @r, align 4, !tbaa [[TAG_9]], !noalias [[TAG_x]] + // CHECK: [[add1:%.*]] = add nsw i32 [[TMP38]], [[TMP37]] + // CHECK: store i32 [[add1]], i32* @r, align 4, !tbaa [[TAG_9]], !noalias [[TAG_x]] + } + + return x; + // CHECK: [[TMP39:%.*]] = load i32*, i32** [[x]], align 8, !tbaa [[TAG_5]], !noalias [[TAG_x]] + // CHECK: [[TMP40:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP39]], i8* [[TMP1]], i32** [[x]], i64 0, metadata [[TAG_x]]), !tbaa [[TAG_5]], !noalias [[TAG_x]] + // CHECK: ret i32* [[TMP40]] +} + +int *bar() { + int *x = a; + return x; + + // CHECK-LABEL: define i32* @bar() + // CHECK-NOT: noalias + // CHECK: ret i32* +} Index: clang/test/CodeGen/restrict/basic_opt_01.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/basic_opt_01.c @@ -0,0 +1,137 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +// Rough test to verify basic functionality of the 'restrict member pointer' rewrite + +// CHECK: @test01A +// CHECK: ret i32 42 +int test01A(int *pA, int *pB) { + int *__restrict prA; + prA = pA; + + *prA = 42; + *pB = 43; + return *prA; +} + +// CHECK: @test01B +// CHECK: ret i32 42 +int test01B(int *__restrict prA, int *pB) { + *prA = 42; + *pB = 43; + return *prA; +} + +// CHECK: @test02A +// CHECK: ret i32 42 +int test02A(int b, int *pA, char *pB, int *pC) { + int *__restrict prA; + prA = pA; + char *__restrict prB; + prB = pB; + char *lp = b ? (char *)prA : (char *)prB; + + *lp = 42; + *pC = 43; + return *lp; +} + +// CHECK: @test02B +// CHECK: ret i32 42 +int test02B(int b, int *__restrict prA, char *__restrict prB, int *pC) { + char *lp = b ? (char *)prA : (char *)prB; + + *lp = 42; + *pC = 43; + return *lp; +} + +// CHECK: @test03 +// CHECK: ret i32 42 +int test03(int n, int *pA, char *pB, int *pC) { + do { + int *__restrict prA; + prA = pA; + + *prA = 42; + *pC = 43; + } while (n--); + return *pA; +} + +// CHECK: @test04A0 +// CHECK: ret i32 42 +int test04A0(int n, int *pA, char *pB, int *pC) { + int *__restrict prA; + do { + prA = pA; + + *prA = 42; + *pC = 43; + } while (n--); + return *prA; +} + +// CHECK: @test04A1 +// CHECK: ret i32 42 +int test04A1(int n, int *pA, char *pB, int *pC) { + int *__restrict prA; + prA = pA; + do { + prA = pA; + + *prA = 42; + *pC = 43; + } while (n--); + return *prA; +} + +// CHECK: @test04B0 +// CHECK: ret i32 42 +int test04B0(int n, int *__restrict prA, char *pB, int *pC) { + do { + prA = prA; + + *prA = 42; + *pC = 43; + } while (n--); + return *prA; +} + +// CHECK: @test04B1 +// CHECK: ret i32 42 +int test04B1(int n, int *__restrict prA, char *pB, int *pC) { + prA = prA; + do { + prA = prA; + + *prA = 42; + *pC = 43; + } while (n--); + return *prA; +} + +// CHECK: @test05A +// CHECK: ret i32 42 +int test05A(int n, int *pA, char *pB, int *pC) { + int *__restrict prA; + prA = pA; + do { + prA++; + + *prA = 42; + *pC = 43; + } while (n--); + return *prA; +} + +// CHECK: @test05B +// CHECK: ret i32 42 +int test05B(int n, int *__restrict prA, char *pB, int *pC) { + do { + prA++; + + *prA = 42; + *pC = 43; + } while (n--); + return *prA; +} Index: clang/test/CodeGen/restrict/basic_opt_02.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/basic_opt_02.c @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +int foo1(int *a, int *restrict b, int c) { + *a = 0; + *b = c; + return *a; // OK: returns 0 +} +// CHECK: @foo1 +// CHECK: ret i32 0 + +int foo2(int *a, int *restrict b, int c) { + int *bc = b + c; + *a = 0; + *bc = c; // OK: bc keeps the restrictness + return *a; // returns 0 +} +// CHECK: @foo2 +// CHECK: ret i32 0 + +static int *copy(int *b) { return b; } + +int foo3(int *a, int *restrict b, int c) { + int *bc = copy(b); // a fix to support this is in the works + *a = 0; + *bc = c; + return *a; +} +// CHECK: @foo3 +// CHECK: ret i32 0 + +// Finally: +inline void update(int *p, int c) { *p = c; } + +int foo6(int *a, int *b, int c) { + int *restrict bc = b; // local restrict + *a = 0; + update(bc, c); // Oops: inlining loses local restrict annotation + return *a; +} + +// CHECK: @foo6 +// CHECK: ret i32 0 + +// Notice the difference with: +int foo7(int *a, int *restrict b, int c) { + *a = 0; + update(b, c); // restrict argument preserved after inlining. + return *a; // returns 0 +} + +// CHECK: @foo7 +// CHECK: ret i32 0 Index: clang/test/CodeGen/restrict/basic_opt_03.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/basic_opt_03.c @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s +// XFAIL: * + +// NOTE: SROA needs to be able to see through llvm.noalias. This is introduced in case of returning of larger structs. +// NOTE2: 20211115: all looks good now... TODO: adapt the test to check that the restrict/no-restrict versions are identical. +struct A { + int a, b, c, d, e, f, g, h; +}; +struct A constructIt(int a) { + struct A tmp = {a, a, a, a, a, a, a, a}; + return tmp; +} +int test_sroa01a(unsigned c) { + int tmp = 0; + for (int i = 0; i < c; ++i) { + struct A a = constructIt(i); + tmp = tmp + a.e; + } + return tmp; +} + +// CHECK: @test_sroa01a +// CHECK: FIXME + +int test_sroa01b(unsigned c) { + int tmp = 0; + for (int i = 0; i < c; ++i) { + struct A a = {i, i, i, i, i, i, i, i}; + tmp = tmp + a.e; + } + return tmp; +} + +// CHECK: @test_sroa01b +// CHECK: FIXME + +int test_sroa01c(unsigned c) { + int tmp = 0; + for (int i = 0; i < c; ++i) { + int *__restrict dummy; // should not influence optimizations ! + struct A a = {i, i, i, i, i, i, i, i}; + tmp = tmp + a.e; + } + return tmp; +} + +// CHECK: @test_sroa01b +// CHECK: FIXME + +int test_sroa02a(unsigned c) { + int tmp = 0; + struct A a; + for (int i = 0; i < c; ++i) { + a = constructIt(i); + tmp = tmp + a.e; + } + return tmp; +} + +// CHECK: @test_sroa02a +// CHECK: FIXME + +int test_sroa02b(unsigned c) { + struct A a; + int tmp = 0; + for (int i = 0; i < c; ++i) { + a = (struct A){i, i, i, i, i, i, i, i}; + tmp = tmp + a.e; + } + return tmp; +} + +// CHECK: @test_sroa02b +// CHECK: FIXME Index: clang/test/CodeGen/restrict/basic_opt_04.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/basic_opt_04.c @@ -0,0 +1,296 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +// verify effect of restrict on optimizations +void dummy_restrict01_n(int *p) { + if (0) { + *p = 0xdeadbeef; + } +} + +void dummy_restrict01_a(int *__restrict p) { + if (0) { + *p = 0xdeadbeef; + } +} + +void dummy_restrict01_r(int *p_) { + int *__restrict p = p_; + if (0) { + *p = 0xdeadbeef; + } +} + +void dummy_restrict01_R(int *p_) { + int *__restrict p; + p = p_; + if (0) { + *p = 0xdeadbeef; + } +} + +void dummy_restrict02_n(int *p) { + p++; + if (0) { + *p = 0xdeadbeef; + } +} + +void dummy_restrict02_a(int *__restrict p) { + p++; + if (0) { + *p = 0xdeadbeef; + } +} + +void dummy_restrict02_r(int *p_) { + int *__restrict p = p_; + p++; + if (0) { + *p = 0xdeadbeef; + } +} + +void dummy_restrict02_R(int *p_) { + int *__restrict p; + p = p_; + p++; + if (0) { + *p = 0xdeadbeef; + } +} + +// --------------------------------- + +int test01_n(int *pA, int c) { + if (0) { + *pA = 0xdeadbeef; + } + return c; +} + +// CHECK: @test01_n +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test01_a(int *__restrict pA, int c) { + if (0) { + *pA = 0xdeadbeef; + } + return c; +} + +// CHECK: @test01_a +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test01_r(int *pA_, int c) { + int *__restrict pA = pA_; + if (0) { + *pA = 0xdeadbeef; + } + return c; +} +// CHECK: @test01_r +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test01_R(int *pA_, int c) { + int *__restrict pA; + pA = pA_; + if (0) { + *pA = 0xdeadbeef; + } + return c; +} +// CHECK: @test01_R +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test01_nn(int *pA, int c) { + dummy_restrict01_n(pA); + return c; +} +// CHECK: @test01_nn +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test01_na(int *pA, int c) { + dummy_restrict01_a(pA); + return c; +} +// CHECK: @test01_na +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test01_nr(int *pA, int c) { + dummy_restrict01_r(pA); + return c; +} +// CHECK: @test01_nr +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test01_nR(int *pA, int c) { + dummy_restrict01_R(pA); + return c; +} +// CHECK: @test01_nR +// CHECK-NOT: .noalias +// CHECK: ret i32 + +// ---------------------------------- +int test02_n(int *pA, int c) { + pA++; + if (0) { + *pA = 0xdeadbeef; + } + return c; +} +// CHECK: @test02_n +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test02_a(int *__restrict pA, int c) { + pA++; + if (0) { + *pA = 0xdeadbeef; + } + return c; +} +// CHECK: @test02_a +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test02_r(int *pA_, int c) { + int *__restrict pA = pA_; + pA++; + if (0) { + *pA = 0xdeadbeef; + } + return c; +} +// CHECK: @test02_r +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test02_R(int *pA_, int c) { + int *__restrict pA; + pA = pA_; + pA++; + if (0) { + *pA = 0xdeadbeef; + } + return c; +} +// CHECK: @test02_R +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test02_nn(int *pA, int c) { + dummy_restrict02_n(pA); + return c; +} +// CHECK: @test02_nn +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test02_na(int *pA, int c) { + dummy_restrict02_a(pA); + return c; +} +// CHECK: @test02_na +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test02_nr(int *pA, int c) { + dummy_restrict02_r(pA); + return c; +} +// CHECK: @test02_nr +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test02_nR(int *pA, int c) { + dummy_restrict02_R(pA); + return c; +} +// CHECK: @test02_nR +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test11_n(int *pA) { + unsigned total = 0; + for (int i = 0; i < 10; ++i) { + int *p = pA; + total = total + 1; + } + return total; +} +// CHECK: @test11_n +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test11_lr(int *pA) { + unsigned total = 0; + for (int i = 0; i < 10; ++i) { + int *__restrict p = pA; + total = total + 1; + } + return total; +} +// CHECK: @test11_lr +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test11_lR(int *pA) { + unsigned total = 0; + for (int i = 0; i < 10; ++i) { + int *__restrict p; + p = pA; + total = total + 1; + } + return total; +} +// CHECK: @test11_lR +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test12_n(int *pA) { + unsigned total = 0; + for (int i = 0; i < 10; ++i) { + int *p = pA; + p++; + total = total + 1; + } + return total; +} +// CHECK: @test12_n +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test12_lr(int *pA) { + unsigned total = 0; + for (int i = 0; i < 10; ++i) { + int *__restrict p = pA; + p++; + total = total + 1; + } + return total; +} +// CHECK: @test12_lr +// CHECK-NOT: .noalias +// CHECK: ret i32 + +int test12_lR(int *pA) { + unsigned total = 0; + for (int i = 0; i < 10; ++i) { + int *__restrict p; + p = pA; + p++; + total = total + 1; + } + return total; +} +// CHECK: @test12_lR +// CHECK-NOT: .noalias +// CHECK: ret i32 Index: clang/test/CodeGen/restrict/escape_through_volatile.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/escape_through_volatile.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +// a volatile pointer can confuse llvm: (p2 depends on p0) +int test_escape_through_volatile_01(int *a_p0) { + int *__restrict p0; + p0 = a_p0; + int *volatile p1 = p0; + int *p2 = p1; + *p0 = 42; + *p2 = 99; + + return *p0; // 42 or 99 +} + +// CHECK: @test_escape_through_volatile_01 +// either a reload or 99, but must never be 42 +// CHECK-NOT: ret i32 42 + +// but not in: +int test_escape_through_volatile_02(int *__restrict p0) { + int *volatile p1 = p0; + int *p2 = p1; + *p0 = 42; + *p2 = 99; + + return *p0; // 42 or 99 +} + +// CHECK: @test_escape_through_volatile_02 +// either a reload or 99, but must never be 42 +// CHECK-NOT: ret i32 42 Index: clang/test/CodeGen/restrict/inlining_01.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/inlining_01.c @@ -0,0 +1,156 @@ +// sfg-check: check resulting chains +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +// check how restrict propagation wrt inlining works + +//#define INLINE __attribute__((alwaysinline)) +//#define INLINE inline +#define INLINE + +// Variations: +// - n : no restrict +// - a : argument restrict +// - R : local restrict + +#define ARGRESTRICT_n +#define ARGRESTRICT_a __restrict +#define ARGRESTRICT_R + +#define LOCALRESTRICT_n(T, A, B) T A = B +#define LOCALRESTRICT_a(T, A, B) T A = B +#define LOCALRESTRICT_R(T, A, B) T __restrict A = B + +#define CREATE_ALL(CS) \ + CS(n, n) \ + CS(a, n) \ + CS(n, a) \ + CS(a, a) \ + CS(R, n) \ + CS(n, R) \ + CS(R, R) + +#define CREATE_SET(A, B) \ + INLINE int set_##A##B(int *ARGRESTRICT_##A pA, int *ARGRESTRICT_##B pB) { \ + LOCALRESTRICT_##A(int *, lpA, pA); \ + LOCALRESTRICT_##B(int *, lpB, pB); \ + *lpA = 42; \ + *lpB = 99; \ + return *lpA; \ + } + +#define CREATE_CALL_SET1(A, B) \ + int test01_nn_call_set_##A##B(int *pA, int *pB) { \ + set_##A##B(pA, pB); \ + return *pA; \ + } + +#define CREATE_CALL_SET2(A, B) \ + int test02_##A##B##_call_set_##A##B(int *ARGRESTRICT_##A pA, int *ARGRESTRICT_##B pB) { \ + LOCALRESTRICT_##A(int *, lpA, pA); \ + LOCALRESTRICT_##B(int *, lpB, pB); \ + set_##A##B(lpA, lpB); \ + return *lpA; \ + } + +#define CREATE_CALL_SET3(A, B) \ + int test03_##A##B##_call_set_nn(int *ARGRESTRICT_##A pA, int *ARGRESTRICT_##B pB) { \ + LOCALRESTRICT_##A(int *, lpA, pA); \ + LOCALRESTRICT_##B(int *, lpB, pB); \ + set_nn(lpA, lpB); \ + return *lpA; \ + } + +CREATE_ALL(CREATE_SET) +CREATE_ALL(CREATE_CALL_SET1) +CREATE_ALL(CREATE_CALL_SET2) +CREATE_ALL(CREATE_CALL_SET3) + +// CHECK-LABEL: @set_nn( +// CHECK-NOT: ret i32 42 + +// CHECK-LABEL: @set_an( +// CHECK: ret i32 42 + +// CHECK-LABEL: @set_na( +// CHECK: ret i32 42 + +// CHECK_LABEL: @set_aa( +// CHECK: ret i32 42 + +// CHECK-LABEL: @set_Rn( +// CHECK: ret i32 42 + +// CHECK-LABEL: @set_nR( +// CHECK: ret i32 42 + +// CHECK-LABEL: @set_RR( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test01_nn_call_set_nn( +// CHECK-NOT: ret i32 42 + +//@ NOTE: missed store-load propagation +// CHECK-LABEL: @test01_nn_call_set_an( +// CHECK-NOT: ret i32 42 + +//@ NOTE: missed store-load propagation +// CHECK-LABEL: @test01_nn_call_set_na( +// CHECK-NOT: ret i32 42 + +//@ NOTE: missed store-load propagation +// CHECK-LABEL: @test01_nn_call_set_aa( +// CHECK-NOT: ret i32 42 + +//@ NOTE: missed store-load propagation +// CHECK-LABEL: @test01_nn_call_set_Rn( +// CHECK-NOT: ret i32 42 + +//@ NOTE: missed store-load propagation +// CHECK-LABEL: @test01_nn_call_set_nR( +// CHECK-NOT: ret i32 42 + +//@ NOTE: missed store-load propagation +// CHECK-LABEL: @test01_nn_call_set_RR( +// CHECK-NOT: ret i32 42 + +// CHECK-LABEL: @test02_nn_call_set_nn( +// CHECK-NOT: ret i32 42 + +// CHECK-LABEL: @test02_an_call_set_an( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test02_na_call_set_na( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test02_aa_call_set_aa( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test02_Rn_call_set_Rn( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test02_nR_call_set_nR( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test02_RR_call_set_RR( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test03_nn_call_set_nn( +// CHECK-NOT: ret i32 42 + +// CHECK-LABEL: @test03_an_call_set_nn( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test03_na_call_set_nn( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test03_aa_call_set_nn( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test03_Rn_call_set_nn( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test03_nR_call_set_nn( +// CHECK: ret i32 42 + +// CHECK-LABEL: @test03_RR_call_set_nn( +// CHECK: ret i32 42 Index: clang/test/CodeGen/restrict/inlining_02.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/inlining_02.c @@ -0,0 +1,144 @@ +// sfg-check: check resulting chains +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +// Base test for restrict propagation with inlining + +//#define INLINE __attribute__((alwaysinline)) +//#define INLINE inline +#define INLINE + +void set_nnn(int *pA, int *pB, int *dummy) { + int *lpA; + lpA = pA; + int *lpB; + lpB = pB; + int *ldummy; + ldummy = dummy; + *lpA = 42; + *lpB = 43; + + *ldummy = 99; +} +// CHECK-LABEL: @set_nnn( + +void set_nna(int *pA, int *pB, int *__restrict dummy) { + int *lpA; + lpA = pA; + int *lpB; + lpB = pB; + int *ldummy; + ldummy = dummy; + *lpA = 42; + *lpB = 43; + + *ldummy = 99; +} +// CHECK-LABEL: @set_nna( + +void set_nnr(int *pA, int *pB, int *dummy) { + int *lpA; + lpA = pA; + int *lpB; + lpB = pB; + int *__restrict ldummy; + ldummy = dummy; + + *lpA = 42; + *lpB = 43; + + *ldummy = 99; +} +// CHECK-LABEL: @set_nnr( + +int test_rr_nnn(int *pA, int *pB, int *dummy) { + int *__restrict lpA; + lpA = pA; + int *__restrict lpB; + lpB = pB; + + set_nnn(lpA, lpB, dummy); + return *lpA; +} + +// CHECK-LABEL: @test_rr_nnn( +// CHECK: ret i32 42 + +int test_rr_nna(int *pA, int *pB, int *dummy) { + int *__restrict lpA; + lpA = pA; + int *__restrict lpB; + lpB = pB; + + set_nna(lpA, lpB, dummy); + return *lpA; +} + +// CHECK-LABEL: @test_rr_nna( +// CHECK: ret i32 42 + +int test_rr_nnr(int *pA, int *pB, int *dummy) { + int *__restrict lpA; + lpA = pA; + int *__restrict lpB; + lpB = pB; + + set_nnr(lpA, lpB, dummy); + return *lpA; +} + +// CHECK-LABEL: @test_rr_nnr( +// CHECK: ret i32 42 + +// ----------------------------------------------------------- + +int test_rr_local_nnn(int *pA, int *pB, int *dummy) { + int *__restrict lpA; + lpA = pA; + int *__restrict lpB; + lpB = pB; + int *ldummy; + ldummy = dummy; + + *lpA = 10; + { + int *l2pA; + l2pA = lpA; + int *l2pB; + l2pB = lpB; + int *l2dummy; + l2dummy = ldummy; + *l2pA = 42; + *l2pB = 43; + + *l2dummy = 99; + } + return *lpA; +} +// CHECK-LABEL: @test_rr_local_nnn( +// CHECK: ret i32 42 + +int test_rr_local_nnr(int *pA, int *pB, int *dummy) { + int *__restrict lpA; + lpA = pA; + int *__restrict lpB; + lpB = pB; + int *ldummy; + ldummy = dummy; + + *lpA = 10; + { + int *l2pA; + l2pA = lpA; + int *l2pB; + l2pB = lpB; + int *__restrict l2dummy; + l2dummy = ldummy; + *l2pA = 42; + *l2pB = 43; + + *l2dummy = 99; + } + return *lpA; +} +// CHECK-LABEL: @test_rr_local_nnr( +// CHECK: ret i32 42 Index: clang/test/CodeGen/restrict/provenance.noalias_reduction_01.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/provenance.noalias_reduction_01.c @@ -0,0 +1,200 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict -fno-experimental-new-pass-manager %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O2 -ffull-restrict -fexperimental-new-pass-manager %s -emit-llvm -o - | FileCheck %s + +// Check that unnecessary llvm.provenance.noalias calls are collapsed + +int *test01(int *p, int n) { + int *__restrict rp; + rp = p; + for (int i = 0; i < n; ++i) { + *rp = 10; + rp++; + rp++; + rp++; + rp++; + } + return rp; +} + +// CHECK-LABEL: @test01( +// CHECK: = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK-NOT: llvm.provenance.noalias + +int *test02(int *p, int n) { + int *__restrict rp; + rp = p; + rp++; + rp++; + rp++; + rp++; + for (int i = 0; i < n; ++i) { + *rp = 10; + rp++; + rp++; + rp++; + rp++; + } + return rp; +} + +// CHECK-LABEL: @test02( +// CHECK: = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK-NOT: llvm.provenance.noalias + +int *test03(int *p, int n) { + int *__restrict rp; + rp = p; + rp++; + rp++; + rp++; + rp++; + for (int i = 0; i < n; ++i) { + *rp = 10; + rp++; + rp++; + if (*rp == 42) { + rp++; + rp++; + } + rp++; + rp++; + } + return rp; +} + +// CHECK-LABEL: @test03( +// CHECK: = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK-NOT: llvm.provenance.noalias + +int *test04(int *p, int n) { + int *__restrict rp; + rp = p; + rp++; + rp++; + rp++; + rp++; + for (int i = 0; i < n; ++i) { + *rp = 10; + rp++; + rp++; + switch (*rp) { + default: + rp++; + case 10: + rp++; + case 20: + rp++; + case 30: + rp++; + break; + } + if (*rp == 42) { + rp++; + rp++; + } + rp++; + rp++; + } + return rp; +} + +// CHECK-LABEL: @test04( +// CHECK: = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK-NOT: llvm.provenance.noalias + +int *test05(int *p, int n) { + int *__restrict rp; + rp = p; + rp++; + rp++; + rp++; + rp++; + for (int i = 0; i < n; ++i) { + *rp = 10; + rp++; + rp++; + switch (*rp) { + default: + rp++; + case 10: + rp++; + case 20: + rp++; + case 30: + rp++; + break; + } + if (*rp == 42) { + rp++; + rp++; + } + rp++; + rp++; + } + return rp; +} + +// CHECK-LABEL: @test05( +// CHECK: = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK-NOT: llvm.provenance.noalias + +int *test06(int *p, int n) { + int *__restrict rp1; + rp1 = p; + // llvm.provenance.noalias rp1 (p) + + { + int *__restrict rp; + rp = p; + // llvm.provenance.noalias rp (p) + // llvm.provenance.noalias rp (rp1) + rp++; + rp++; + rp++; + rp++; + for (int i = 0; i < n; ++i) { + *rp = 10; + rp = rp1; + rp++; + rp++; + + switch (*rp) { + default: + rp++; + case 10: + rp++; + case 20: + rp++; + case 30: + rp++; + break; + } + if (*rp == 42) { + rp++; + rp++; + } + rp++; + rp++; + } + // llvm.provenance.noalias rp (p -> (p || rp1)) + return rp; + } +} + +// CHECK-LABEL: @test06( +// CHECK: = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64 +// CHECK: = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK: = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 +// CHECK-NOT: llvm.provenance.noalias + +// CHECK: declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64 Index: clang/test/CodeGen/restrict/struct.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/struct.c @@ -0,0 +1,130 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +int r; +void ex1(int *); + +struct FOO { + int *restrict rp0; + int *restrict rp1; + int *restrict rp2; +}; + +void test_FOO_local(int *pA, int *pB, int *pC) { + struct FOO tmp = {pA, pB, pC}; + *tmp.rp0 = 42; + *tmp.rp1 = 43; +} +// CHECK-LABEL: void @test_FOO_local( +// CHECK: [[tmp:%.*]] = alloca %struct.FOO, align 8 +// CHECK: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FOOs.i64(%struct.FOO* [[tmp]], i64 0, metadata [[TAG_6:!.*]]) +// CHECK: [[rp0:%.*]] = getelementptr inbounds %struct.FOO, %struct.FOO* [[tmp]], i32 0, i32 0 +// CHECK: [[rp01:%.*]] = getelementptr inbounds %struct.FOO, %struct.FOO* [[tmp]], i32 0, i32 0 +// CHECK: [[TMP5:%.*]] = load i32*, i32** [[rp01]], align 8, !tbaa [[TAG_9:!.*]], !noalias [[TAG_6]] +// CHECK: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP1]], i32** [[rp01]], i64 0, metadata [[TAG_6]]), !tbaa [[TAG_9]], !noalias [[TAG_6]] +// CHECK: store i32 42, i32* [[TMP6]], align 4, !tbaa [[TAG_13:!.*]], !noalias [[TAG_6]] +// CHECK: [[rp12:%.*]] = getelementptr inbounds %struct.FOO, %struct.FOO* [[tmp]], i32 0, i32 1 +// CHECK: [[TMP7:%.*]] = load i32*, i32** [[rp12]], align 8, !tbaa [[TAG_11:!.*]], !noalias [[TAG_6]] +// CHECK: [[TMP8:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP7]], i8* [[TMP1]], i32** [[rp12]], i64 0, metadata [[TAG_6]]), !tbaa [[TAG_11]], !noalias [[TAG_6]] +// CHECK: store i32 43, i32* [[TMP8]], align 4, !tbaa [[TAG_13]], !noalias [[TAG_6]] +// CHECK: ret void + +void test_FOO_arg_pointer(struct FOO *p) { + *p->rp0 = 42; + *p->rp1 = 43; +} + +// define void @test_FOO_arg_pointer(%struct.FOO* %p) #0 !noalias !15 { +// CHECK: void @test_FOO_arg_pointer(%struct.FOO* [[p:%.*]]) #0 !noalias [[TAG_15:!.*]] { +// CHECK: [[p_addr:%.*]] = alloca %struct.FOO*, align 8 +// CHECK-NEXT: store %struct.FOO* [[p]], %struct.FOO** [[p_addr]], align 8, !tbaa [[TAG_2:!.*]], !noalias [[TAG_15]] +// CHECK-NEXT: [[TMP0:%.*]] = load %struct.FOO*, %struct.FOO** [[p_addr]], align 8, !tbaa [[TAG_2]], !noalias [[TAG_15]] +// CHECK-NEXT: [[rp0:%.*]] = getelementptr inbounds %struct.FOO, %struct.FOO* [[TMP0]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** [[rp0]], align 8, !tbaa [[TAG_9:!.*]], !noalias [[TAG_15]] +// CHECK-NEXT: [[TMP2:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP1]], i8* null, i32** [[rp0]], i64 0, metadata [[TAG_15]]), !tbaa [[TAG_9]], !noalias [[TAG_15]] +// CHECK-NEXT: store i32 42, i32* [[TMP2]], align 4, !tbaa [[TAG_13:!.*]], !noalias [[TAG_15]] +// CHECK-NEXT: [[TMP3:%.*]] = load %struct.FOO*, %struct.FOO** [[p_addr]], align 8, !tbaa [[TAG_2]], !noalias [[TAG_15]] +// CHECK-NEXT: [[rp1:%.*]] = getelementptr inbounds %struct.FOO, %struct.FOO* [[TMP3]], i32 0, i32 1 +// CHECK-NEXT: [[TMP4:%.*]] = load i32*, i32** [[rp1]], align 8, !tbaa [[TAG_11:!.*]], !noalias [[TAG_15]] +// CHECK-NEXT: [[TMP5:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP4]], i8* null, i32** [[rp1]], i64 0, metadata [[TAG_15]]), !tbaa [[TAG_11]], !noalias [[TAG_15]] +// CHECK-NEXT: store i32 43, i32* [[TMP5]], align 4, !tbaa [[TAG_13]], !noalias [[TAG_15]] +// CHECK-NEXT: ret void + +void test_FOO_arg_value(struct FOO p) { + *p.rp0 = 42; + *p.rp1 = 43; +} +// NOTE: the struct is mapped 'byval', the scope will be introduced after inlining. + +// define void @test_FOO_arg_value(%struct.FOO* byval(%struct.FOO) align 8 %p) #0 !noalias !18 { +// CHECK: void @test_FOO_arg_value(%struct.FOO* byval(%struct.FOO) align 8 %p) #0 !noalias [[TAG_18:!.*]] { +// CHECK: [[rp0:%.*]] = getelementptr inbounds %struct.FOO, %struct.FOO* [[p:%.*]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[rp0]], align 8, !tbaa [[TAG_9:!.*]], !noalias [[TAG_18]] +// CHECK-NEXT: [[TMP1:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP0]], i8* null, i32** [[rp0]], i64 0, metadata [[TAG_18]]), !tbaa [[TAG_9]], !noalias [[TAG_18]] +// CHECK-NEXT: store i32 42, i32* [[TMP1]], align 4, !tbaa [[TAG_13:!.*]], !noalias [[TAG_18]] +// CHECK-NEXT: [[rp1:%.*]] = getelementptr inbounds %struct.FOO, %struct.FOO* [[p]], i32 0, i32 1 +// CHECK-NEXT: [[TMP2:%.*]] = load i32*, i32** [[rp1]], align 8, !tbaa [[TAG_11:!.*]], !noalias [[TAG_18]] +// CHECK-NEXT: [[TMP3:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP2]], i8* null, i32** [[rp1]], i64 0, metadata [[TAG_18]]), !tbaa [[TAG_11]], !noalias [[TAG_18]] +// CHECK-NEXT: store i32 43, i32* [[TMP3]], align 4, !tbaa [[TAG_13]], !noalias [[TAG_18]] +// CHECK-NEXT: ret void + +struct FOO test_FOO_pass(struct FOO p) { + return p; +} + +// define void @test_FOO_pass(%struct.FOO* noalias sret(%struct.FOO) align 8 %agg.result, %struct.FOO* byval(%struct.FOO) align 8 %p) #0 !noalias !21 { +// CHECK: void @test_FOO_pass(%struct.FOO* noalias sret(%struct.FOO) align 8 %agg.result, %struct.FOO* byval(%struct.FOO) align 8 %p) #0 !noalias [[TAG_21:!.*]] { +// CHECK: [[TMP0:%.*]] = call %struct.FOO* @llvm.noalias.copy.guard.p0s_struct.FOOs.p0i8(%struct.FOO* [[p:%.*]], i8* null, metadata [[TAG_24:!.*]], metadata [[TAG_21]]) +// CHECK-NEXT: [[TMP1:%.*]] = bitcast %struct.FOO* [[agg_result:%.*]] to i8* +// CHECK-NEXT: [[TMP2:%.*]] = bitcast %struct.FOO* [[TMP0]] to i8* +// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP1]], i8* align 8 [[TMP2]], i64 24, i1 false), !tbaa.struct [[TAG_28:!.*]], !noalias [[TAG_21]] +// CHECK-NEXT: ret void + +struct FUM { + struct FOO m; +}; + +void test_FUM_local(int *pA, int *pB, int *pC) { + struct FUM tmp = {{pA, pB, pC}}; + *tmp.m.rp0 = 42; + *tmp.m.rp1 = 43; +} + +// CHECK-LABEL: void @test_FUM_local( +// CHECK: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* [[tmp]], i64 0, metadata [[TAG_29:!.*]]) +// CHECK: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5:%.*]], i8* [[TMP1]], i32** [[rp02:%.*]], i64 0, metadata [[TAG_29]]), !tbaa [[TAG_32:!.*]], !noalias [[TAG_29]] +// CHECK: [[TMP8:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP7:%.*]], i8* [[TMP1]], i32** [[rp14:%.*]], i64 0, metadata [[TAG_29]]), !tbaa [[TAG_34:!.*]], !noalias [[TAG_29]] + +void test_FUM_arg_pointer(struct FUM *p) { + *p->m.rp0 = 42; + *p->m.rp1 = 43; +} +// define void @test_FUM_arg_pointer(%struct.FUM* %p) #0 !noalias !35 { +// CHECK: void @test_FUM_arg_pointer(%struct.FUM* [[p:%.*]]) #0 !noalias [[TAG_35:!.*]] { +// CHECK: [[TMP2:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP1:%.*]], i8* null, i32** [[rp0:%.*]], i64 0, metadata [[TAG_35]]), !tbaa [[TAG_32:!.*]], !noalias [[TAG_35]] +// CHECK: [[TMP5:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP4:%.*]], i8* null, i32** [[rp1:%.*]], i64 0, metadata [[TAG_35]]), !tbaa [[TAG_34:!.*]], !noalias [[TAG_35]] + +void test_FUM_arg_value(struct FUM p) { + *p.m.rp0 = 42; + *p.m.rp1 = 43; +} + +// define void @test_FUM_arg_value(%struct.FUM* byval(%struct.FUM) align 8 %p) #0 !noalias !38 { +// CHECK: void @test_FUM_arg_value(%struct.FUM* byval(%struct.FUM) align 8 %p) #0 !noalias [[TAG_38:!.*]] { +// CHECK: [[TMP1:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP0:%.*]], i8* null, i32** [[rp0:%.*]], i64 0, metadata [[TAG_38]]), !tbaa [[TAG_32:!.*]], !noalias [[TAG_38]] +// CHECK: [[TMP3:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP2:%.*]], i8* null, i32** [[rp1:%.*]], i64 0, metadata [[TAG_38]]), !tbaa [[TAG_34:!.*]], !noalias [[TAG_38]] + +struct FUM test_FUM_pass(struct FUM p) { + return p; +} + +// define void @test_FUM_pass(%struct.FUM* noalias sret(%struct.FUM) align 8 %agg.result, %struct.FUM* byval(%struct.FUM) align 8 %p) #0 !noalias !41 { +// CHECK: void @test_FUM_pass(%struct.FUM* noalias sret(%struct.FUM) align 8 %agg.result, %struct.FUM* byval(%struct.FUM) align 8 %p) #0 !noalias [[TAG_41:!.*]] { +// CHECK: [[TMP0:%.*]] = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* [[p:%.*]], i8* null, metadata [[TAG_24:!.*]], metadata [[TAG_41]]) +// CHECK-NEXT: [[TMP1:%.*]] = bitcast %struct.FUM* [[agg_result:%.*]] to i8* +// CHECK-NEXT: [[TMP2:%.*]] = bitcast %struct.FUM* [[TMP0]] to i8* +// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP1]], i8* align 8 [[TMP2]], i64 24, i1 false), !tbaa.struct [[TAG_28:!.*]], !noalias [[TAG_41]] +// CHECK-NEXT: ret void + +// indices for llvm.noalias.copy.guard + +// CHECK: [[TAG_24]] = !{i64 24, i64 0, i64 8, i64 3} Index: clang/test/CodeGen/restrict/struct_member_01.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/struct_member_01.c @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +struct FOO { + int *__restrict pA; + int *__restrict pB; +}; + +int test00a(int *pA, int *pB) { + int *__restrict rpA; + int *__restrict rpB; + rpA = pA; + rpB = pB; + + *rpA = 42; + *rpB = 43; + return *rpA; +} + +// CHECK-LABEL: @test00a( +// CHECK: ret i32 42 + +int test00b(int *pA, int *pB) { + int *__restrict rp[2]; + rp[0] = pA; + rp[1] = pB; + + *rp[0] = 42; + *rp[1] = 43; + return *rp[0]; +} + +// CHECK-LABEL: @test00b( +// CHECK: ret i32 42 + +int test01(struct FOO *p0, struct FOO *p1) { + *p0->pA = 42; + *p1->pA = 43; + + return *p0->pA; // 42 or 43 +} +// CHECK-LABEL: @test01( +// CHECK-NOT: ret i32 42 + +int test11(struct FOO *p0, struct FOO *p1) { + *p0->pA = 42; + *p1->pB = 43; + + return *p0->pA; // 42 +} + +// CHECK-LABEL: @test11( +// CHECK: ret i32 42 + +int test21(struct FOO p0, struct FOO p1) { + *p0.pA = 42; + *p1.pB = 43; + + return *p0.pA; // 42 +} + +// CHECK-LABEL: @test21( +// CHECK: ret i32 42 + +int test31(struct FOO *p0, struct FOO *__restrict p1) { + *p0->pA = 42; + *p1->pA = 43; + + return *p0->pA; // 42 +} + +// CHECK-LABEL: @test31( +// CHECK: ret i32 42 Index: clang/test/CodeGen/restrict/struct_member_02.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/struct_member_02.c @@ -0,0 +1,110 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s + +//#define __restrict volatile + +// this test checks for what variables a restrict scope is created + +struct FOO_ipp { + int **p; +}; + +struct FOO_irpp { + int *__restrict *p; +}; + +struct FOO_iprp { + int dummy; + int **__restrict p; +}; + +struct FOO_irprp { + int *__restrict *__restrict p; +}; + +struct FOO_NESTED { + struct FOO_iprp m; +}; + +struct FOO_NESTED_A { + struct FOO_iprp m[2][3][4]; +}; + +typedef struct FOO_NESTED FUM; +typedef int *__restrict t_irp; + +int foo(int **p) { + struct FOO_ipp m1; // no + struct FOO_irpp m2; // no + struct FOO_iprp m3; // yes + struct FOO_irprp m4; // yes + struct FOO_NESTED m5; // yes + struct FOO_NESTED m6[2][4][5]; // yes + struct FOO_NESTED_A m7[2][4][5]; // yes + t_irp p0; // yes + FUM m8[3]; // yes + int *a1[2]; // no + int **a2[2]; // no + int *__restrict *a3[2]; // no + int **__restrict a4[2]; // yes + int **__restrict a5[2][3][4]; // yes + int *__restrict *a6; // no + m1.p = p; + m2.p = p; + m3.p = p; + m4.p = p; + a1[0] = *p; + a1[1] = *p; + + return **m1.p + **m2.p + **m3.p + **m4.p + *a1[0] + *a1[1]; +} + +// check the scopes of various variables +// CHECK-LABEL: @foo( + +// the local variables: +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK: alloca +// CHECK-NOT: alloca + +// the local variables that have a restrict scope: +// CHECK: llvm.noalias.decl +// CHECK: llvm.noalias.decl +// CHECK: llvm.noalias.decl +// CHECK: llvm.noalias.decl +// CHECK: llvm.noalias.decl +// CHECK: llvm.noalias.decl +// CHECK: llvm.noalias.decl +// CHECK: llvm.noalias.decl +// CHECK: llvm.noalias.decl +// CHECK-NOT: llvm.noalias.decl +// CHECK: ret i32 + +// the restrict related metadata +// CHECK: foo: unknown scope +// CHECK-NEXT: foo +// CHECK-NOT: foo: +// CHECK: foo: m3 +// CHECK-NEXT: foo: m4 +// CHECK-NEXT: foo: m5 +// CHECK-NEXT: foo: m6 +// CHECK-NEXT: foo: m7 +// CHECK-NEXT: foo: p0 +// CHECK-NEXT: foo: m8 +// CHECK-NEXT: foo: a4 +// CHECK-NEXT: foo: a5 +// CHECK-NOT: foo: Index: clang/test/CodeGen/restrict/struct_member_03.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/struct_member_03.c @@ -0,0 +1,100 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +struct FOO { + int *__restrict pA; + int *__restrict pB; +}; + +int test10(int *pA, int *pB) { + struct FOO rp; + rp.pA = pA; + rp.pB = pB; + + *rp.pA = 42; + *rp.pB = 99; + + return *rp.pA; // 42 +} +// CHECK-LABEL: @test10( +// CHECK: ret i32 42 + +int test11(struct FOO rp) { + *rp.pA = 42; + *rp.pB = 99; + + return *rp.pA; // 42 +} +// CHECK-LABEL: @test11( +// CHECK: ret i32 42 + +int test12(struct FOO *rp) { + *rp->pA = 42; + *rp->pB = 99; + + return *rp->pA; // 42 +} +// CHECK-LABEL: @test12( +// CHECK: ret i32 42 + +int test20(int *pA, int *pB) { + struct FOO rp0; + struct FOO rp1; + rp0.pB = pA; + rp1.pB = pB; + + *rp0.pB = 42; + *rp1.pB = 99; + + return *rp0.pB; // 42 +} +// CHECK-LABEL: @test20( +// CHECK: ret i32 42 + +int test21(struct FOO rp0, struct FOO rp1) { + *rp0.pB = 42; + *rp1.pB = 99; + + return *rp0.pB; // 42 +} +// CHECK-LABEL: @test21( +// CHECK: ret i32 42 + +int test22(struct FOO *rp0, struct FOO *rp1) { + *rp0->pB = 42; + *rp1->pB = 99; + + return *rp0->pB; // needs load +} +// CHECK-LABEL: @test22( +// CHECK-NOT: ret i32 42 +// CHECK-NOT: ret i32 99 + +int test23(struct FOO *rp0, struct FOO *rp1) { + *rp0->pA = 42; + *rp1->pB = 99; + + return *rp0->pA; // 42, rp0->pA and rp1->pB are not overlapping +} +// CHECK-LABEL: @test23( +// CHECK: ret i32 42 + +int test24(struct FOO *__restrict rp0, struct FOO *rp1) { + *rp0->pB = 42; + *rp1->pB = 99; + + return *rp0->pB; // 42 +} +// CHECK-LABEL: @test24( +// CHECK: ret i32 42 + +int test25(struct FOO *p0, struct FOO *rp1) { + struct FOO *__restrict rp0; + rp0 = p0; + *rp0->pB = 42; + *rp1->pB = 99; + + return *rp0->pB; // 42 +} +// CHECK-LABEL: @test25( +// CHECK: ret i32 42 Index: clang/test/CodeGen/restrict/struct_member_04.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/struct_member_04.c @@ -0,0 +1,168 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +// restrict member pointers and inlining - basic functionality test + +struct FOO { + int *__restrict pA; + int *__restrict pB; +}; + +void setFOO(struct FOO *p) { + *p->pA = 42; + *p->pB = 43; +} + +int test10(int *pA, int *pB, int *pC) { + + *pA = 40; + { + struct FOO rp; + rp.pA = pA; + rp.pB = pB; + + setFOO(&rp); + + *pC = 99; + return *rp.pA; // 42 + } +} + +// CHECK-LABEL: @test10( +// CHECK: ret i32 42 + +int test11(int *pA, int *pB, int *pC) { + + *pA = 40; + { + struct FOO rp; + rp.pA = pA; + rp.pB = pB; + + setFOO(&rp); + + *pC = 99; + } + return *pA; // 42 // should be, but llvm does not see it +} + +// CHECK-LABEL: @test11( +// CHECK-NOT: ret i32 40 +// CHECK-NOT: ret i32 42 +// CHECK-NOT: ret i32 43 +// CHECK-NOT: ret i32 99 + +int test12(int *pA, int *pB, int *pC) { + + *pA = 40; + { + struct FOO rp; + rp.pA = pA; + rp.pB = pB; + + setFOO(&rp); + } + + *pC = 99; + return *pA; // 42 or 99 +} + +// CHECK-LABEL: @test12( +// CHECK-NOT: ret i32 40 +// CHECK-NOT: ret i32 42 +// CHECK-NOT: ret i32 43 +// CHECK-NOT: ret i32 99 + +// out-of-function scope +int getFOO(struct FOO *p) { + return *p->pA; +} + +// fully defined +int test20(int *pA, int *pC) { + *pA = 42; + { + struct FOO rp; + rp.pA = pA; + *pC = 99; + return getFOO(&rp); + } +} +// CHECK-LABEL: @test20( +// CHECK: ret i32 42 + +// fully defined +int test21(int *pA, int *pC) { + *pA = 42; + *pC = 99; + { + struct FOO rp; + rp.pA = pA; + return getFOO(&rp); + } +} + +// CHECK-LABEL: @test21( +// CHECK: ret i32 % + +// mixed defined +int test22(int *pA, struct FOO *pB0, int b0, int *pC) { + *pA = 42; + { + struct FOO rp; + rp.pA = pA; + *pC = 99; + return getFOO(b0 ? &rp : pB0); + } +} +// CHECK-LABEL: @test22( +// CHECK: ret i32 % + +// mixed-mixed defined +int test23(int *pA, struct FOO *pB0, int b0, struct FOO *pB1, int b1, int *pC) { + *pA = 41; + { + struct FOO rp; + rp.pA = pA; + *pC = 98; + return test22(pA, b1 ? &rp : pB0, b0, pC); + } +} +// CHECK-LABEL: @test23( +// CHECK: ret i32 % + +// fully defined +int test24(int *pA, int *pB0, int b0, int *pB1, int b1, int *pC) { + *pA = 40; + { + struct FOO fb0; + fb0.pA = pB0; + { + struct FOO fb1; + fb1.pA = pB1; + + return test23(pA, &fb0, b0, &fb1, b1, pC); + } + } +} + +// CHECK-LABEL: @test24( +// CHECK: ret i32 % + +int test25(int *pA, int b0, int b1, int *pC) { + *pA = 40; + { + struct FOO fb0; + fb0.pA = pA; + { + struct FOO fb1; + fb1.pA = pA; + + return test23(pA, &fb0, b0, &fb1, b1, pC); + } + } +} + +// CHECK-LABEL: @test25( +// FIXME: should be: ret i32 42 +// CHECK: ret i32 % Index: clang/test/CodeGen/restrict/struct_member_05.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/struct_member_05.c @@ -0,0 +1,107 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +// restrict member pointers and inlining - basic functionality test + +struct FOO { + int *__restrict pA; + int *__restrict pB; +}; + +struct FOO_plain { + int *pA; + int *pB; +}; + +int test10(int *pA, int *pB, int *pC) { + + *pA = 40; + { + struct FOO rp; + rp.pA = pA; + rp.pB = pB; + + { + struct FOO *p = &rp; + *p->pA = 42; + *p->pB = 43; + } + + *pC = 99; + return *rp.pA; // 42 + } +} + +// CHECK-LABEL: @test10( +// CHECK: ret i32 42 + +int test11(int *pA, int *pB, int *pC) { + + *pA = 40; + { + struct FOO rp; + rp.pA = pA; + rp.pB = pB; + + { + *rp.pA = 42; + *rp.pB = 43; + } + + *pC = 99; + return *rp.pA; // 42 + } +} + +// CHECK-LABEL: @test11( +// CHECK: ret i32 42 + +int test12a(int *pA, int *pB, int *pC, struct FOO *pF) { + + *pA = 40; + { + struct FOO rp; + rp.pA = pA; + rp.pB = pB; + + { + struct FOO *p = pF ? pF : &rp; + *p->pA = 42; + *p->pB = 43; + } + + *pC = 99; + return *rp.pA; // 42 or 40 + } +} + +// CHECK-LABEL: @test12a( +// CHECK-NOT: ret i32 40 +// CHECK-NOT: ret i32 42 +// CHECK-NOT: ret i32 43 +// CHECK-NOT: ret i32 99 + +int test12b(int *pA, int *pB, int *pC, struct FOO_plain *pF) { + + *pA = 40; + { + struct FOO_plain rp; + rp.pA = pA; + rp.pB = pB; + + { + struct FOO_plain *p = pF ? pF : &rp; + *p->pA = 42; + *p->pB = 43; + } + + *pC = 99; + return *rp.pA; // 42 or 40 or 99 or ... + } +} + +// CHECK-LABEL: @test12b( +// CHECK-NOT: ret i32 40 +// CHECK-NOT: ret i32 42 +// CHECK-NOT: ret i32 43 +// CHECK-NOT: ret i32 99 Index: clang/test/CodeGen/restrict/struct_member_06.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/struct_member_06.c @@ -0,0 +1,108 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +// restrict member pointers and inlining - basic functionality test + +struct FOO { + int *__restrict p; +}; + +struct FOO_plain { + int *pA; + int *pB; +}; + +int test01_p_pp(int c, int *pA, int *pB) { + int *__restrict rpA; + rpA = pA; + int *__restrict rpB; + rpB = pB; + + int *p = c ? rpA : rpB; + + return *p; +} +// CHECK-LABEL: @test01_p_pp( +// CHECK: @llvm.noalias.decl +// CHECK-NEXT: @llvm.noalias.decl +// CHECK-NEXT: icmp +// CHECK-NEXT: @llvm.provenance.noalias +// CHECK-NEXT: @llvm.provenance.noalias +// CHECK-NEXT: select +// CHECK-NEXT: select +// CHECK-NEXT: load +// CHECK-NEXT: ret i32 + +int test01_p_ss(int c, int *pA, int *pB) { + struct FOO spA; + spA.p = pA; + struct FOO spB; + spB.p = pB; + + int *p = c ? spA.p : spB.p; + + return *p; +} +// CHECK-LABEL: @test01_p_ss( +// CHECK: @llvm.noalias.decl +// CHECK-NEXT: @llvm.noalias.decl +// CHECK-NEXT: icmp +// CHECK-NEXT: @llvm.provenance.noalias +// CHECK-NEXT: @llvm.provenance.noalias +// CHECK-NEXT: select +// CHECK-NEXT: select +// CHECK-NEXT: load +// CHECK-NEXT: ret i32 + +int test01_s_ss(int c, int *pA, int *pB) { + struct FOO spA; + spA.p = pA; + struct FOO spB; + spB.p = pB; + + { + struct FOO p = c ? spA : spB; + + return *p.p; + } +} +// CHECK-LABEL: @test01_s_ss( +// CHECK: @llvm.noalias.decl +// CHECK-NEXT: @llvm.noalias.decl +// CHECK-NEXT: @llvm.noalias.decl +// CHECK-NEXT: icmp +// CHECK-NEXT: @llvm.provenance.noalias +// CHECK-NEXT: @llvm.provenance.noalias +// CHECK-NEXT: select +// CHECK-NEXT: select +// CHECK-NEXT: @llvm.provenance.noalias +// CHECK-NEXT: load +// CHECK-NEXT: ret i32 + +// FIXME: this one currently results in bad code :( +int test01_ps_ss(int c, int *pA, int *pB) { + struct FOO spA; + spA.p = pA; + struct FOO spB; + spB.p = pB; + + struct FOO *p = c ? &spA : &spB; + + return *p->p; +} +// CHECK-LABEL: @test01_ps_ss( +// CHECK: ret i32 + +int test01_ps_psps(int c, struct FOO *ppA, struct FOO *ppB) { + struct FOO *p = c ? ppA : ppB; + + return *p->p; +} +// CHECK-LABEL: @test01_ps_psps( +// CHECK: icmp +// CHECK-NEXT: select +// CHECK-NEXT: getelementptr +// CHECK-NEXT: load +// CHECK-NEXT: llvm.provenance.noalias +// CHECK-NEXT: load +// CHECK-NEXT: ret i32 Index: clang/test/CodeGen/restrict/struct_member_07.c =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/struct_member_07.c @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s + +struct FOO { + int *__restrict pA; +}; + +struct BAR { + int *pA; +}; + +static void adaptFOO(struct FOO *p) { + *p->pA = 99; +}; + +static void adaptBAR(struct BAR *p) { + *p->pA = 99; +}; + +static void adaptInt(int *p) { + *p = 99; +}; + +// has 'unknown scope': caller: no, callee: yes +int test10(int *pA, struct FOO *pB) { + *pA = 42; + adaptFOO(pB); + return *pA; +} +// CHECK-LABEL: @test10( +// CHECK: ret i32 42 + +// has 'unknown scope': caller: yes, callee: no +int test11(int *pA, struct FOO *pB) { + *pB->pA = 42; + adaptInt(pA); + return *pB->pA; +} +// CHECK-LABEL: @test11( +// CHECK: ret i32 42 + +// has 'unknown scope': caller: no, callee: no +int test12(int *pA, struct BAR *pB) { + *pA = 42; + adaptBAR(pB); + return *pA; +} +// CHECK-LABEL: @test12( +// CHECK-NOT: ret i32 42 + +// has 'unknown scope': caller: yes, callee: yes +int test13(int *pA, struct FOO *pB) { + *pB->pA = 41; // introduce 'unknown scope' + *pA = 42; + adaptFOO(pB); + return *pA; +} + +// CHECK-LABEL: @test13( +// CHECK: ret i32 42 Index: clang/test/CodeGen/restrict/struct_member_08.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/restrict/struct_member_08.cpp @@ -0,0 +1,162 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - -DDUMMY_BEFORE | FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - -DDUMMY_BEFORE | FileCheck %s --check-prefixes=CHECK + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - -DDUMMY_AFTER | FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - -DDUMMY_AFTER | FileCheck %s --check-prefixes=CHECK + +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - -DDUMMY_BEFORE -DDUMMY_AFTER | FileCheck %s --check-prefixes=CHECK +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -O2 -ffull-restrict %s -emit-llvm -o - -DDUMMY_BEFORE -DDUMMY_AFTER | FileCheck %s --check-prefixes=CHECK + +// NOTE: this test in C++ mode + +struct Fum { + Fum(unsigned long long d) { + ptr1 = ((int *)(d & 0xffffffff)); + ptr2 = ((int *)((d >> 32) & 0xffffffff)); + } + Fum(const Fum &) = default; + +#ifdef DUMMY_BEFORE + int *dummyb0; + int *dummyb1; +#endif + int *__restrict ptr1; + int *__restrict ptr2; +#ifdef DUMMY_AFTER + int *dummya0; + int *dummya1; +#endif +}; + +static Fum pass(Fum d) { return d; } + +int test_Fum_01(unsigned long long data, int *p1) { + Fum tmp = {data}; + + int *p0 = tmp.ptr1; + + *p0 = 42; + *p1 = 99; + return *p0; +} +// CHECK-LABEL: @_Z11test_Fum_01yPi +// CHECK-NOT: alloca +// CHECK: ret i32 42 + +int test_Fum_02(unsigned long long data) { + Fum tmp = {data}; + + int *p0 = tmp.ptr1; + int *p1 = tmp.ptr2; + + *p0 = 42; + *p1 = 99; + return *p0; +} +// CHECK-LABEL: @_Z11test_Fum_02y +// CHECK-NOT: alloca +// CHECK: ret i32 42 + +int test_Fum_pass_01(unsigned long long data, int *p1) { + Fum tmp = {data}; + + int *p0 = pass(tmp).ptr1; + + *p0 = 42; + *p1 = 99; + return *p0; +} +// CHECK-LABEL: @_Z16test_Fum_pass_01yPi +// CHECK-NOT: alloca +// CHECK: ret i32 42 + +int test_Fum_pass_02(unsigned long long data) { + Fum tmp = {data}; + + int *p0 = pass(tmp).ptr1; + int *p1 = pass(tmp).ptr2; + + *p0 = 42; + *p1 = 99; + return *p0; +} +// CHECK-LABEL: @_Z16test_Fum_pass_02y +// CHECK-NOT: alloca +// CHECK: ret i32 42 + +int test_Fum_pass_03(unsigned long long data) { + Fum tmp = {data}; + + int *b0 = tmp.ptr1; + *b0 = 42; + + int *p0 = pass(tmp).ptr1; + + *p0 = 99; + return *b0; // 99 +} +// CHECK-LABEL: @_Z16test_Fum_pass_03y +// CHECK-NOT: alloca +// CHECK-NOT: ret i32 42 +// CHECK: ret i32 99 + +int test_Fum_pass_04(unsigned long long data, int *px) { + Fum tmp = {data}; + + int *b0 = tmp.ptr1; + *b0 = 42; + tmp.ptr1 = px; + + int *p0 = pass(tmp).ptr1; + + *p0 = 99; + return *b0; // 42 or 99 +} +// CHECK-LABEL: @_Z16test_Fum_pass_04yPi +// CHECK-NOT: alloca +// CHECK-NOT: ret i32 42 +// CHECK-NOT: ret i32 99 +// CHECK: ret i32 % + +class S { +public: + S(int *d) : data(d) {} + int *getData() { return data; } + +private: + int *__restrict__ data; +}; + +int test_S__01(int *pA, long N) { + int *__restrict__ x = pA; + + *x = 42; + { + S s(x + N); + *s.getData() = 99; + } + return *x; // N could be 0 +} + +// CHECK-LABEL: @_Z10test_S__01Pil +// CHECK-NOT: alloca +// CHECK-NOT: ret i32 42 +// CHECK: ret i32 % + +int test_S__02(int *pA, long N) { + int *__restrict__ x = pA; + + *x = 42; + { + S s(x + N); + *s.getData() = 99; + return *x; // restrict rules say that N cannot be 0 + } +} + +// CHECK-LABEL: @_Z10test_S__02Pil +// CHECK-NOT: alloca +// CHECK: ret i32 42 Index: clang/test/CodeGenCUDA/builtins-amdgcn.cu =================================================================== --- clang/test/CodeGenCUDA/builtins-amdgcn.cu +++ clang/test/CodeGenCUDA/builtins-amdgcn.cu @@ -36,19 +36,20 @@ } __global__ - // CHECK-LABEL: @_Z12test_ds_fmaxf( - // CHECK-NEXT: entry: - // CHECK-NEXT: [[SRC_ADDR:%.*]] = alloca float, align 4, addrspace(5) - // CHECK-NEXT: [[X:%.*]] = alloca float, align 4, addrspace(5) - // CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast float addrspace(5)* [[SRC_ADDR]] to float* - // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast float addrspace(5)* [[X]] to float* - // CHECK-NEXT: store float [[SRC:%.*]], float* [[SRC_ADDR_ASCAST]], align 4 - // CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[SRC_ADDR_ASCAST]], align 4 - // CHECK-NEXT: [[TMP1:%.*]] = call contract float @llvm.amdgcn.ds.fmax.f32(float addrspace(3)* @_ZZ12test_ds_fmaxfE6shared, float [[TMP0]], i32 0, i32 0, i1 false) - // CHECK-NEXT: store volatile float [[TMP1]], float* [[X_ASCAST]], align 4 - // CHECK-NEXT: ret void // void +// CHECK-LABEL: @_Z12test_ds_fmaxf( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[SRC_ADDR:%.*]] = alloca float, align 4, addrspace(5) +// CHECK-NEXT: [[X:%.*]] = alloca float, align 4, addrspace(5) +// CHECK-NEXT: [[SRC_ADDR_ASCAST:%.*]] = addrspacecast float addrspace(5)* [[SRC_ADDR]] to float* +// CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast float addrspace(5)* [[X]] to float* +// CHECK-NEXT: store float [[SRC:%.*]], float* [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[SRC_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = call contract float @llvm.amdgcn.ds.fmax.f32(float addrspace(3)* @_ZZ12test_ds_fmaxfE6shared, float [[TMP0]], i32 0, i32 0, i1 false) +// CHECK-NEXT: store volatile float [[TMP1]], float* [[X_ASCAST]], align 4 +// CHECK-NEXT: ret void +// test_ds_fmax(float src) { __shared__ float shared; volatile float x = __builtin_amdgcn_ds_fmaxf(&shared, src, 0, 0, false); @@ -185,17 +186,20 @@ // CHECK-NEXT: [[SHARED_ADDR_ASCAST:%.*]] = addrspacecast float* addrspace(5)* [[SHARED_ADDR]] to float** // CHECK-NEXT: [[X_ASCAST:%.*]] = addrspacecast float addrspace(5)* [[X]] to float* // CHECK-NEXT: [[TMP0:%.*]] = addrspacecast float addrspace(1)* [[SHARED_COERCE:%.*]] to float* -// CHECK-NEXT: store float* [[TMP0]], float** [[SHARED_ASCAST]], align 8 -// CHECK-NEXT: [[SHARED1:%.*]] = load float*, float** [[SHARED_ASCAST]], align 8 -// CHECK-NEXT: store float [[SRC:%.*]], float* [[SRC_ADDR_ASCAST]], align 4 -// CHECK-NEXT: store float* [[SHARED1]], float** [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP1:%.*]] = load float*, float** [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: [[TMP2:%.*]] = addrspacecast float* [[TMP1]] to float addrspace(3)* -// CHECK-NEXT: [[TMP3:%.*]] = load float, float* [[SRC_ADDR_ASCAST]], align 4 -// CHECK-NEXT: [[TMP4:%.*]] = call contract float @llvm.amdgcn.ds.fmin.f32(float addrspace(3)* [[TMP2]], float [[TMP3]], i32 0, i32 0, i1 false) -// CHECK-NEXT: store volatile float [[TMP4]], float* [[X_ASCAST]], align 4 -// CHECK-NEXT: [[TMP5:%.*]] = load float*, float** [[SHARED_ADDR_ASCAST]], align 8 -// CHECK-NEXT: call void @_Z4funcPf(float* [[TMP5]]) #[[ATTR8:[0-9]+]] +// CHECK-NEXT: store float* [[TMP0]], float** [[SHARED_ASCAST]], align 8, !noalias !2 +// CHECK-NEXT: [[TMP1:%.*]] = load float*, float** [[SHARED_ASCAST]], align 8, !noalias !2 +// CHECK-NEXT: [[SHARED1:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[TMP1]], i8* null, float** [[SHARED_ASCAST]], i64 0, metadata [[META2:![0-9]+]]), !noalias !2 +// CHECK-NEXT: store float [[SRC:%.*]], float* [[SRC_ADDR_ASCAST]], align 4, !noalias !2 +// CHECK-NEXT: store float* [[SHARED1]], float** [[SHARED_ADDR_ASCAST]], align 8, !noalias !2 +// CHECK-NEXT: [[TMP2:%.*]] = load float*, float** [[SHARED_ADDR_ASCAST]], align 8, !noalias !2 +// CHECK-NEXT: [[TMP3:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[TMP2]], i8* null, float** [[SHARED_ADDR_ASCAST]], i64 0, metadata [[META2]]), !noalias !2 +// CHECK-NEXT: [[TMP4:%.*]] = addrspacecast float* [[TMP3]] to float addrspace(3)* +// CHECK-NEXT: [[TMP5:%.*]] = load float, float* [[SRC_ADDR_ASCAST]], align 4, !noalias !2 +// CHECK-NEXT: [[TMP6:%.*]] = call contract float @llvm.amdgcn.ds.fmin.f32(float addrspace(3)* [[TMP4]], float [[TMP5]], i32 0, i32 0, i1 false), !noalias !2 +// CHECK-NEXT: store volatile float [[TMP6]], float* [[X_ASCAST]], align 4, !noalias !2 +// CHECK-NEXT: [[TMP7:%.*]] = load float*, float** [[SHARED_ADDR_ASCAST]], align 8, !noalias !2 +// CHECK-NEXT: [[TMP8:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[TMP7]], i8* null, float** [[SHARED_ADDR_ASCAST]], i64 0, metadata [[META2]]), !noalias !2 +// CHECK-NEXT: call void @_Z4funcPf(float* [[TMP8]]) #[[ATTR9:[0-9]+]], !noalias !2 // CHECK-NEXT: ret void // __global__ void test_ds_fmin_func(float src, float *__restrict shared) { Index: clang/test/Driver/full-restrict.c =================================================================== --- /dev/null +++ clang/test/Driver/full-restrict.c @@ -0,0 +1,23 @@ +// RUN: %clang -### -ffull-restrict -S %s 2>&1 | FileCheck %s --check-prefix=CHECK_FULL +// RUN: %clang -### -fno-full-restrict -S %s 2>&1 | FileCheck %s --check-prefix=CHECK_NO_FULL +// RUN: %clang -### -S %s 2>&1 | FileCheck %s --check-prefix=CHECK_NOTHING + +// FIXME: How to really check the 'enabled by defaultl' case ? +// FIXME: This test is not able to verify that the 'default = enable' really works :( + +// CHECK_FULL-NOT: -fno-full-restrict +// CHECK_FULL-NOT: -use-noalias-intrinsic-during-inlining +// CHECK_FULL: -ffull-restrict +// CHECK_FULL-NOT: -fno-full-restrict +// CHECK_FULL-NOT: -use-noalias-intrinsic-during-inlining + +// CHECK_NO_FULL-NOT: -ffull-restrict +// CHECK_NO_FULL-NOT: -use-noalias-intrinsic-during-inlining +// CHECK_NO_FULL: -fno-full-restrict +// CHECK_NO_FULL: -use-noalias-intrinsic-during-inlining=scopes +// CHECK_NO_FULL-NOT: -ffull-restrict +// CHECK_NO_FULL-NOT: -use-noalias-intrinsic-during-inlining + +// CHECK_NOTHING-NOT: -fno-full-restrict +// CHECK_NOTHING-NOT: -ffull-restrict +// CHECK_NOTHING-NOT: -use-noalias-intrinsic-during-inlining Index: clang/test/OpenMP/cancel_codegen.cpp =================================================================== --- clang/test/OpenMP/cancel_codegen.cpp +++ clang/test/OpenMP/cancel_codegen.cpp @@ -384,29 +384,29 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2:[0-9]+]] -// CHECK1-NEXT: [[TMP13:%.*]] = icmp ne i32 [[TMP12]], 0 -// CHECK1-NEXT: br i1 [[TMP13]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK1-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK1-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK1-NEXT: br i1 [[TMP17]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK1: .cancel.exit.i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: .cancel.continue.i: -// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .omp_outlined..1.exit: -// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK1-NEXT: ret i32 0 // // @@ -1004,29 +1004,29 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2:[0-9]+]] -// CHECK2-NEXT: [[TMP13:%.*]] = icmp ne i32 [[TMP12]], 0 -// CHECK2-NEXT: br i1 [[TMP13]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK2-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK2-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK2-NEXT: br i1 [[TMP17]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK2: .cancel.exit.i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: .cancel.continue.i: -// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .omp_outlined..1.exit: -// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK2-NEXT: ret i32 0 // // @@ -1631,29 +1631,29 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB12:[0-9]+]]) #[[ATTR2:[0-9]+]] -// CHECK3-NEXT: [[TMP11:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i32 4) #[[ATTR2]] -// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK3-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB12:[0-9]+]]) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i32 4) #[[ATTR2]], !noalias !8 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK3: .cancel.exit.i: -// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__EXIT:%.*]] // CHECK3: .cancel.continue.i: -// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__EXIT]] // CHECK3: .omp_outlined..exit: -// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK3-NEXT: ret i32 0 // // @@ -2258,29 +2258,29 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB12:[0-9]+]]) #[[ATTR2:[0-9]+]] -// CHECK4-NEXT: [[TMP11:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i32 4) #[[ATTR2]] -// CHECK4-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK4-NEXT: br i1 [[TMP12]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK4-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB12:[0-9]+]]) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK4-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i32 4) #[[ATTR2]], !noalias !8 +// CHECK4-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK4-NEXT: br i1 [[TMP16]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK4: .cancel.exit.i: -// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__EXIT:%.*]] // CHECK4: .cancel.continue.i: -// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__EXIT]] // CHECK4: .omp_outlined..exit: -// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK4-NEXT: ret i32 0 // // @@ -2878,29 +2878,29 @@ // CHECK7-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK7-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK7-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK7-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK7-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK7-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK7-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK7-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK7-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK7-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK7-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK7-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2:[0-9]+]] -// CHECK7-NEXT: [[TMP13:%.*]] = icmp ne i32 [[TMP12]], 0 -// CHECK7-NEXT: br i1 [[TMP13]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK7-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK7-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK7-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK7-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK7-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK7-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK7-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK7-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK7-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK7-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK7-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK7-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK7-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK7-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK7-NEXT: br i1 [[TMP17]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK7: .cancel.exit.i: -// CHECK7-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK7-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK7-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK7: .cancel.continue.i: -// CHECK7-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK7-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK7-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK7: .omp_outlined..1.exit: -// CHECK7-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK7-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK7-NEXT: ret i32 0 // // @@ -3498,29 +3498,29 @@ // CHECK8-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK8-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK8-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK8-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK8-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK8-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK8-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK8-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK8-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK8-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK8-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK8-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2:[0-9]+]] -// CHECK8-NEXT: [[TMP13:%.*]] = icmp ne i32 [[TMP12]], 0 -// CHECK8-NEXT: br i1 [[TMP13]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK8-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK8-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK8-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK8-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK8-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK8-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK8-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK8-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK8-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK8-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK8-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK8-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK8-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK8-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK8-NEXT: br i1 [[TMP17]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK8: .cancel.exit.i: -// CHECK8-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK8-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK8-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK8: .cancel.continue.i: -// CHECK8-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK8-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK8-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK8: .omp_outlined..1.exit: -// CHECK8-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK8-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK8-NEXT: ret i32 0 // // @@ -4125,29 +4125,29 @@ // CHECK9-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK9-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK9-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK9-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK9-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK9-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK9-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK9-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK9-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK9-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK9-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK9-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK9-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK9-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK9-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB12:[0-9]+]]) #[[ATTR2:[0-9]+]] -// CHECK9-NEXT: [[TMP11:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i32 4) #[[ATTR2]] -// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK9-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK9-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK9-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK9-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK9-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK9-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK9-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK9-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK9-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK9-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK9-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK9-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB12:[0-9]+]]) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK9-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i32 4) #[[ATTR2]], !noalias !8 +// CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK9-NEXT: br i1 [[TMP16]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK9: .cancel.exit.i: -// CHECK9-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK9-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK9-NEXT: br label [[DOTOMP_OUTLINED__EXIT:%.*]] // CHECK9: .cancel.continue.i: -// CHECK9-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK9-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK9-NEXT: br label [[DOTOMP_OUTLINED__EXIT]] // CHECK9: .omp_outlined..exit: -// CHECK9-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK9-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK9-NEXT: ret i32 0 // // @@ -4752,29 +4752,29 @@ // CHECK10-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK10-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK10-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK10-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK10-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK10-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK10-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK10-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK10-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK10-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK10-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK10-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK10-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK10-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK10-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB12:[0-9]+]]) #[[ATTR2:[0-9]+]] -// CHECK10-NEXT: [[TMP11:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i32 4) #[[ATTR2]] -// CHECK10-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK10-NEXT: br i1 [[TMP12]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK10-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK10-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK10-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK10-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK10-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK10-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK10-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK10-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK10-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK10-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK10-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK10-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB12:[0-9]+]]) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK10-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i32 4) #[[ATTR2]], !noalias !8 +// CHECK10-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK10-NEXT: br i1 [[TMP16]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK10: .cancel.exit.i: -// CHECK10-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK10-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK10-NEXT: br label [[DOTOMP_OUTLINED__EXIT:%.*]] // CHECK10: .cancel.continue.i: -// CHECK10-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK10-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK10-NEXT: br label [[DOTOMP_OUTLINED__EXIT]] // CHECK10: .omp_outlined..exit: -// CHECK10-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK10-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK10-NEXT: ret i32 0 // // Index: clang/test/OpenMP/cancellation_point_codegen.cpp =================================================================== --- clang/test/OpenMP/cancellation_point_codegen.cpp +++ clang/test/OpenMP/cancellation_point_codegen.cpp @@ -378,36 +378,36 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2:[0-9]+]] -// CHECK1-NEXT: [[TMP13:%.*]] = icmp ne i32 [[TMP12]], 0 -// CHECK1-NEXT: br i1 [[TMP13]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK1-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK1-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK1-NEXT: br i1 [[TMP17]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK1: .cancel.exit.i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: .cancel.continue.i: -// CHECK1-NEXT: [[TMP14:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2]] -// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTCANCEL_EXIT1_I:%.*]], label [[DOTCANCEL_CONTINUE2_I:%.*]] +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2]], !noalias !8 +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[DOTCANCEL_EXIT1_I:%.*]], label [[DOTCANCEL_CONTINUE2_I:%.*]] // CHECK1: .cancel.exit1.i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .cancel.continue2.i: -// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .omp_outlined..1.exit: -// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK1-NEXT: ret i32 0 // // @@ -433,29 +433,29 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK1-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2]] -// CHECK1-NEXT: [[TMP13:%.*]] = icmp ne i32 [[TMP12]], 0 -// CHECK1-NEXT: br i1 [[TMP13]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META11]]), !noalias !14 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META16]]), !noalias !14 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2]], !noalias !14 +// CHECK1-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK1-NEXT: br i1 [[TMP17]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK1: .cancel.exit.i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__2_EXIT:%.*]] // CHECK1: .cancel.continue.i: -// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 +// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__2_EXIT]] // CHECK1: .omp_outlined..2.exit: -// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 // CHECK1-NEXT: ret i32 0 // // @@ -1008,36 +1008,36 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2:[0-9]+]] -// CHECK2-NEXT: [[TMP13:%.*]] = icmp ne i32 [[TMP12]], 0 -// CHECK2-NEXT: br i1 [[TMP13]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META5]]), !noalias !8 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !8 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !8 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !8 +// CHECK2-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2:[0-9]+]], !noalias !8 +// CHECK2-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK2-NEXT: br i1 [[TMP17]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK2: .cancel.exit.i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: .cancel.continue.i: -// CHECK2-NEXT: [[TMP14:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2]] -// CHECK2-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 -// CHECK2-NEXT: br i1 [[TMP15]], label [[DOTCANCEL_EXIT1_I:%.*]], label [[DOTCANCEL_CONTINUE2_I:%.*]] +// CHECK2-NEXT: [[TMP18:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2]], !noalias !8 +// CHECK2-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK2-NEXT: br i1 [[TMP19]], label [[DOTCANCEL_EXIT1_I:%.*]], label [[DOTCANCEL_CONTINUE2_I:%.*]] // CHECK2: .cancel.exit1.i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .cancel.continue2.i: -// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .omp_outlined..1.exit: -// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !8 // CHECK2-NEXT: ret i32 0 // // @@ -1063,29 +1063,29 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK2-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP11]], i32 4) #[[ATTR2]] -// CHECK2-NEXT: [[TMP13:%.*]] = icmp ne i32 [[TMP12]], 0 -// CHECK2-NEXT: br i1 [[TMP13]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META11]]), !noalias !14 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META16]]), !noalias !14 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP15]], i32 4) #[[ATTR2]], !noalias !14 +// CHECK2-NEXT: [[TMP17:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK2-NEXT: br i1 [[TMP17]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK2: .cancel.exit.i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__2_EXIT:%.*]] // CHECK2: .cancel.continue.i: -// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 +// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__2_EXIT]] // CHECK2: .omp_outlined..2.exit: -// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !14 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/debug-info-complex-byval.cpp =================================================================== --- clang/test/OpenMP/debug-info-complex-byval.cpp +++ clang/test/OpenMP/debug-info-complex-byval.cpp @@ -10,23 +10,22 @@ ; } - // CHECK1-LABEL: define {{[^@]+}}@_Z1av // CHECK1-SAME: () #[[ATTR0:[0-9]+]] !dbg [[DBG6:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[B:%.*]] = alloca { float, float }, align 4 // CHECK1-NEXT: [[B_CASTED:%.*]] = alloca i64, align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata { float, float }* [[B]], metadata [[META10:![0-9]+]], metadata !DIExpression()), !dbg [[DBG12:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load { float, float }, { float, float }* [[B]], align 4, !dbg [[DBG13:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[B_CASTED]] to { float, float }*, !dbg [[DBG13]] -// CHECK1-NEXT: store { float, float } [[TMP0]], { float, float }* [[CONV]], align 4, !dbg [[DBG13]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[B_CASTED]], align 8, !dbg [[DBG13]] -// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i64 [[TMP1]]), !dbg [[DBG13]] -// CHECK1-NEXT: ret void, !dbg [[DBG14:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata { float, float }* [[B]], metadata [[META11:![0-9]+]], metadata !DIExpression()), !dbg [[DBG13:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load { float, float }, { float, float }* [[B]], align 4, !dbg [[DBG14:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[B_CASTED]] to { float, float }*, !dbg [[DBG14]] +// CHECK1-NEXT: store { float, float } [[TMP0]], { float, float }* [[CONV]], align 4, !dbg [[DBG14]] +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[B_CASTED]], align 8, !dbg [[DBG14]] +// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i64 [[TMP1]]), !dbg [[DBG14]] +// CHECK1-NEXT: ret void, !dbg [[DBG15:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@.omp_outlined._debug__ -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], <2 x float> [[B_COERCE:%.*]]) #[[ATTR2:[0-9]+]] !dbg [[DBG15:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], <2 x float> [[B_COERCE:%.*]]) #[[ATTR2:[0-9]+]] !dbg [[DBG16:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[B:%.*]] = alloca { float, float }, align 4 // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -34,31 +33,32 @@ // CHECK1-NEXT: [[TMP0:%.*]] = bitcast { float, float }* [[B]] to <2 x float>* // CHECK1-NEXT: store <2 x float> [[B_COERCE]], <2 x float>* [[TMP0]], align 4 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META23:![0-9]+]], metadata !DIExpression()), !dbg [[DBG24:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META24:![0-9]+]], metadata !DIExpression()), !dbg [[DBG25:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META25:![0-9]+]], metadata !DIExpression()), !dbg [[DBG24]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata { float, float }* [[B]], metadata [[META26:![0-9]+]], metadata !DIExpression()), !dbg [[DBG27:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG28:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META26:![0-9]+]], metadata !DIExpression()), !dbg [[DBG25]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata { float, float }* [[B]], metadata [[META27:![0-9]+]], metadata !DIExpression()), !dbg [[DBG28:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG29:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@.omp_outlined. -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[B:%.*]]) #[[ATTR3:[0-9]+]] !dbg [[DBG29:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[B:%.*]]) #[[ATTR3:[0-9]+]] !dbg [[DBG30:![0-9]+]] !noalias !34 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca i64, align 8 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META33:![0-9]+]], metadata !DIExpression()), !dbg [[DBG34:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META37:![0-9]+]], metadata !DIExpression()), !dbg [[DBG38:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META35:![0-9]+]], metadata !DIExpression()), !dbg [[DBG34]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META39:![0-9]+]], metadata !DIExpression()), !dbg [[DBG38]] // CHECK1-NEXT: store i64 [[B]], i64* [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[B_ADDR]], metadata [[META36:![0-9]+]], metadata !DIExpression()), !dbg [[DBG34]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[B_ADDR]] to { float, float }*, !dbg [[DBG37:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG37]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG37]] -// CHECK1-NEXT: [[TMP2:%.*]] = bitcast { float, float }* [[CONV]] to <2 x float>*, !dbg [[DBG37]] -// CHECK1-NEXT: [[TMP3:%.*]] = load <2 x float>, <2 x float>* [[TMP2]], align 8, !dbg [[DBG37]] -// CHECK1-NEXT: call void @.omp_outlined._debug__(i32* [[TMP0]], i32* [[TMP1]], <2 x float> [[TMP3]]) #[[ATTR4:[0-9]+]], !dbg [[DBG37]] -// CHECK1-NEXT: ret void, !dbg [[DBG37]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[B_ADDR]], metadata [[META40:![0-9]+]], metadata !DIExpression()), !dbg [[DBG38]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[B_ADDR]] to { float, float }*, !dbg [[DBG41:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG41]] +// CHECK1-NEXT: [[TMP1:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP0]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META34:![0-9]+]]), !dbg [[DBG41]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG41]] +// CHECK1-NEXT: [[TMP3:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP2]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META34]]), !dbg [[DBG41]] +// CHECK1-NEXT: [[TMP4:%.*]] = bitcast { float, float }* [[CONV]] to <2 x float>*, !dbg [[DBG41]] +// CHECK1-NEXT: [[TMP5:%.*]] = load <2 x float>, <2 x float>* [[TMP4]], align 8, !dbg [[DBG41]] +// CHECK1-NEXT: call void @.omp_outlined._debug__(i32* [[TMP1]], i32* [[TMP3]], <2 x float> [[TMP5]]) #[[ATTR5:[0-9]+]], !dbg [[DBG41]] +// CHECK1-NEXT: ret void, !dbg [[DBG41]] // -// \ No newline at end of file Index: clang/test/OpenMP/debug-info-openmp-array.cpp =================================================================== --- clang/test/OpenMP/debug-info-openmp-array.cpp +++ clang/test/OpenMP/debug-info-openmp-array.cpp @@ -21,24 +21,24 @@ // CHECK1-NEXT: [[SAVED_STACK:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8 // CHECK1-NEXT: store i32 [[M]], i32* [[M_ADDR]], align 4 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[M_ADDR]], metadata [[META11:![0-9]+]], metadata !DIExpression()), !dbg [[DBG12:![0-9]+]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META13:![0-9]+]], metadata !DIExpression()), !dbg [[DBG14:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load i32, i32* [[M_ADDR]], align 4, !dbg [[DBG15:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !dbg [[DBG16:![0-9]+]] -// CHECK1-NEXT: [[TMP2:%.*]] = call i8* @llvm.stacksave(), !dbg [[DBG16]] -// CHECK1-NEXT: store i8* [[TMP2]], i8** [[SAVED_STACK]], align 8, !dbg [[DBG16]] -// CHECK1-NEXT: [[VLA:%.*]] = alloca i32, i64 [[TMP1]], align 16, !dbg [[DBG16]] -// CHECK1-NEXT: store i64 [[TMP1]], i64* [[__VLA_EXPR0]], align 8, !dbg [[DBG16]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[__VLA_EXPR0]], metadata [[META17:![0-9]+]], metadata !DIExpression()), !dbg [[DBG19:![0-9]+]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[VLA]], metadata [[META20:![0-9]+]], metadata !DIExpression()), !dbg [[DBG24:![0-9]+]] -// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB4:[0-9]+]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* [[M_ADDR]], i64 [[TMP1]], i32* [[VLA]]), !dbg [[DBG25:![0-9]+]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8, !dbg [[DBG26:![0-9]+]] -// CHECK1-NEXT: call void @llvm.stackrestore(i8* [[TMP3]]), !dbg [[DBG26]] -// CHECK1-NEXT: ret void, !dbg [[DBG26]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[M_ADDR]], metadata [[META12:![0-9]+]], metadata !DIExpression()), !dbg [[DBG13:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META14:![0-9]+]], metadata !DIExpression()), !dbg [[DBG15:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, i32* [[M_ADDR]], align 4, !dbg [[DBG16:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !dbg [[DBG17:![0-9]+]] +// CHECK1-NEXT: [[TMP2:%.*]] = call i8* @llvm.stacksave(), !dbg [[DBG17]] +// CHECK1-NEXT: store i8* [[TMP2]], i8** [[SAVED_STACK]], align 8, !dbg [[DBG17]] +// CHECK1-NEXT: [[VLA:%.*]] = alloca i32, i64 [[TMP1]], align 16, !dbg [[DBG17]] +// CHECK1-NEXT: store i64 [[TMP1]], i64* [[__VLA_EXPR0]], align 8, !dbg [[DBG17]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[__VLA_EXPR0]], metadata [[META18:![0-9]+]], metadata !DIExpression()), !dbg [[DBG20:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[VLA]], metadata [[META21:![0-9]+]], metadata !DIExpression()), !dbg [[DBG25:![0-9]+]] +// CHECK1-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB4:[0-9]+]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*), i32* [[M_ADDR]], i64 [[TMP1]], i32* [[VLA]]), !dbg [[DBG26:![0-9]+]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8, !dbg [[DBG27:![0-9]+]] +// CHECK1-NEXT: call void @llvm.stackrestore(i8* [[TMP3]]), !dbg [[DBG27]] +// CHECK1-NEXT: ret void, !dbg [[DBG27]] // // // CHECK1-LABEL: define {{[^@]+}}@.omp_outlined._debug__ -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[M:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[CEN:%.*]]) #[[ATTR3:[0-9]+]] !dbg [[DBG27:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[M:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[CEN:%.*]]) #[[ATTR3:[0-9]+]] !dbg [[DBG28:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -56,99 +56,99 @@ // CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[I3:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META35:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META36:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META37:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META38:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37]] // CHECK1-NEXT: store i32* [[M]], i32** [[M_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[M_ADDR]], metadata [[META38:![0-9]+]], metadata !DIExpression()), !dbg [[DBG39:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[M_ADDR]], metadata [[META39:![0-9]+]], metadata !DIExpression()), !dbg [[DBG40:![0-9]+]] // CHECK1-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META40:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META41:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37]] // CHECK1-NEXT: store i32* [[CEN]], i32** [[CEN_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[CEN_ADDR]], metadata [[META41:![0-9]+]], metadata !DIExpression()), !dbg [[DBG42:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[M_ADDR]], align 8, !dbg [[DBG43:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG43]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[CEN_ADDR]], align 8, !dbg [[DBG43]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IV]], metadata [[META44:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTCAPTURE_EXPR_]], metadata [[META45:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4, !dbg [[DBG46:![0-9]+]] -// CHECK1-NEXT: store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4, !dbg [[DBG46]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTCAPTURE_EXPR_1]], metadata [[META45]], metadata !DIExpression()), !dbg [[DBG36]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !dbg [[DBG46]] -// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP4]], 0, !dbg [[DBG43]] -// CHECK1-NEXT: [[DIV:%.*]] = sdiv i32 [[SUB]], 1, !dbg [[DBG43]] -// CHECK1-NEXT: [[SUB2:%.*]] = sub nsw i32 [[DIV]], 1, !dbg [[DBG43]] -// CHECK1-NEXT: store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !dbg [[DBG43]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META47:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36]] -// CHECK1-NEXT: store i32 0, i32* [[I]], align 4, !dbg [[DBG48:![0-9]+]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !dbg [[DBG46]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 0, [[TMP5]], !dbg [[DBG43]] -// CHECK1-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]], !dbg [[DBG43]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[CEN_ADDR]], metadata [[META42:![0-9]+]], metadata !DIExpression()), !dbg [[DBG43:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[M_ADDR]], align 8, !dbg [[DBG44:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[CEN_ADDR]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IV]], metadata [[META45:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTCAPTURE_EXPR_]], metadata [[META46:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4, !dbg [[DBG47:![0-9]+]] +// CHECK1-NEXT: store i32 [[TMP3]], i32* [[DOTCAPTURE_EXPR_]], align 4, !dbg [[DBG47]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTCAPTURE_EXPR_1]], metadata [[META46]], metadata !DIExpression()), !dbg [[DBG37]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !dbg [[DBG47]] +// CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP4]], 0, !dbg [[DBG44]] +// CHECK1-NEXT: [[DIV:%.*]] = sdiv i32 [[SUB]], 1, !dbg [[DBG44]] +// CHECK1-NEXT: [[SUB2:%.*]] = sub nsw i32 [[DIV]], 1, !dbg [[DBG44]] +// CHECK1-NEXT: store i32 [[SUB2]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !dbg [[DBG44]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META48:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37]] +// CHECK1-NEXT: store i32 0, i32* [[I]], align 4, !dbg [[DBG49:![0-9]+]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !dbg [[DBG47]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 0, [[TMP5]], !dbg [[DBG44]] +// CHECK1-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]], !dbg [[DBG44]] // CHECK1: omp.precond.then: -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_LB]], metadata [[META49:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36]] -// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG50:![0-9]+]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_UB]], metadata [[META51:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !dbg [[DBG43]] -// CHECK1-NEXT: store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_STRIDE]], metadata [[META52:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36]] -// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IS_LAST]], metadata [[META53:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36]] -// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I3]], metadata [[META47]], metadata !DIExpression()), !dbg [[DBG36]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG43]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG43]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG54:![0-9]+]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !dbg [[DBG43]] -// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP9]], [[TMP10]], !dbg [[DBG50]] -// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG50]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_LB]], metadata [[META50:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37]] +// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG51:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_UB]], metadata [[META52:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !dbg [[DBG44]] +// CHECK1-NEXT: store i32 [[TMP6]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_STRIDE]], metadata [[META53:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37]] +// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IS_LAST]], metadata [[META54:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37]] +// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I3]], metadata [[META48]], metadata !DIExpression()), !dbg [[DBG37]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG44]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 [[TMP8]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG55:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !dbg [[DBG44]] +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP9]], [[TMP10]], !dbg [[DBG51]] +// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG51]] // CHECK1: cond.true: -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !dbg [[DBG43]] -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !dbg [[DBG44]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG51]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG51]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ], !dbg [[DBG50]] -// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG43]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[TMP11]], [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ], !dbg [[DBG51]] +// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG44]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP14]], [[TMP15]], !dbg [[DBG43]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG43]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP14]], [[TMP15]], !dbg [[DBG44]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG44]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP16]], 1, !dbg [[DBG48]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG48]] -// CHECK1-NEXT: store i32 [[ADD]], i32* [[I3]], align 4, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[I3]], align 4, !dbg [[DBG55:![0-9]+]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[I3]], align 4, !dbg [[DBG57:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP18]] to i64, !dbg [[DBG58:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[IDXPROM]], !dbg [[DBG58]] -// CHECK1-NEXT: store i32 [[TMP17]], i32* [[ARRAYIDX]], align 4, !dbg [[DBG59:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG60:![0-9]+]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP16]], 1, !dbg [[DBG49]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG49]] +// CHECK1-NEXT: store i32 [[ADD]], i32* [[I3]], align 4, !dbg [[DBG49]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[I3]], align 4, !dbg [[DBG56:![0-9]+]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[I3]], align 4, !dbg [[DBG58:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP18]] to i64, !dbg [[DBG59:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[IDXPROM]], !dbg [[DBG59]] +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[ARRAYIDX]], align 4, !dbg [[DBG60:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG61:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG54]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG55]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG50]] -// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP19]], 1, !dbg [[DBG43]] -// CHECK1-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG43]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG54]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP19]], 1, !dbg [[DBG44]] +// CHECK1-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG44]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG55]], !llvm.loop [[LOOP62:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]], !dbg [[DBG54]] +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]], !dbg [[DBG55]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG54]] -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4, !dbg [[DBG54]] -// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP21]]), !dbg [[DBG62:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_PRECOND_END]], !dbg [[DBG54]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG55]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4, !dbg [[DBG55]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP21]]), !dbg [[DBG63:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_PRECOND_END]], !dbg [[DBG55]] // CHECK1: omp.precond.end: -// CHECK1-NEXT: ret void, !dbg [[DBG63:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG64:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@.omp_outlined. -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[M:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[CEN:%.*]]) #[[ATTR3]] !dbg [[DBG64:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i32* nonnull align 4 dereferenceable(4) [[M:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[CEN:%.*]]) #[[ATTR3]] !dbg [[DBG65:![0-9]+]] !noalias !66 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -156,23 +156,24 @@ // CHECK1-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[CEN_ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META65:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META69:![0-9]+]], metadata !DIExpression()), !dbg [[DBG70:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META67:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META71:![0-9]+]], metadata !DIExpression()), !dbg [[DBG70]] // CHECK1-NEXT: store i32* [[M]], i32** [[M_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[M_ADDR]], metadata [[META68:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[M_ADDR]], metadata [[META72:![0-9]+]], metadata !DIExpression()), !dbg [[DBG70]] // CHECK1-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META69:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META73:![0-9]+]], metadata !DIExpression()), !dbg [[DBG70]] // CHECK1-NEXT: store i32* [[CEN]], i32** [[CEN_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[CEN_ADDR]], metadata [[META70:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66]] -// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[M_ADDR]], align 8, !dbg [[DBG71:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG71]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[CEN_ADDR]], align 8, !dbg [[DBG71]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG71]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG71]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[M_ADDR]], align 8, !dbg [[DBG71]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32*, i32** [[CEN_ADDR]], align 8, !dbg [[DBG71]] -// CHECK1-NEXT: call void @.omp_outlined._debug__(i32* [[TMP3]], i32* [[TMP4]], i32* [[TMP5]], i64 [[TMP1]], i32* [[TMP6]]) #[[ATTR4:[0-9]+]], !dbg [[DBG71]] -// CHECK1-NEXT: ret void, !dbg [[DBG71]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[CEN_ADDR]], metadata [[META74:![0-9]+]], metadata !DIExpression()), !dbg [[DBG70]] +// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[M_ADDR]], align 8, !dbg [[DBG75:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG75]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[CEN_ADDR]], align 8, !dbg [[DBG75]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG75]] +// CHECK1-NEXT: [[TMP4:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP3]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META66:![0-9]+]]), !dbg [[DBG75]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG75]] +// CHECK1-NEXT: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META66]]), !dbg [[DBG75]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32*, i32** [[M_ADDR]], align 8, !dbg [[DBG75]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32*, i32** [[CEN_ADDR]], align 8, !dbg [[DBG75]] +// CHECK1-NEXT: call void @.omp_outlined._debug__(i32* [[TMP4]], i32* [[TMP6]], i32* [[TMP7]], i64 [[TMP1]], i32* [[TMP8]]) #[[ATTR4:[0-9]+]], !dbg [[DBG75]] +// CHECK1-NEXT: ret void, !dbg [[DBG75]] // -// \ No newline at end of file Index: clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp +++ clang/test/OpenMP/distribute_parallel_for_reduction_task_codegen.cpp @@ -548,61 +548,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -1167,61 +1171,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/for_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/for_reduction_task_codegen.cpp +++ clang/test/OpenMP/for_reduction_task_codegen.cpp @@ -457,61 +457,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -985,61 +989,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/master_taskloop_firstprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_firstprivate_codegen.cpp +++ clang/test/OpenMP/master_taskloop_firstprivate_codegen.cpp @@ -296,7 +296,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -447,7 +448,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp +++ clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp @@ -601,73 +601,78 @@ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, i8***, i8***)* -// CHECK1-NEXT: call void [[TMP27]](i8* [[TMP26]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP28]], align 8 -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP34:%.*]] = bitcast i32* [[TMP31]] to i8* -// CHECK1-NEXT: [[TMP35:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP32]], i8* [[TMP34]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP35]] to i32* -// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP37:%.*]] = load i16*, i16** [[TMP36]], align 8 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP24]], 2 -// CHECK1-NEXT: [[TMP39:%.*]] = udiv exact i64 [[TMP38]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP33]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK1-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to i64* -// CHECK1-NEXT: store i64 [[TMP39]], i64* [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP29]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = bitcast i16* [[TMP37]] to i8* -// CHECK1-NEXT: [[TMP44:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP42]], i8* [[TMP43]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP44]] to i16* -// CHECK1-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK1-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK1-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK1-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, i8***, i8***)* +// CHECK1-NEXT: call void [[TMP37]](i8* [[TMP36]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP38:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP44:%.*]] = bitcast i32* [[TMP41]] to i8* +// CHECK1-NEXT: [[TMP45:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP42]], i8* [[TMP44]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP45]] to i32* +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP47:%.*]] = load i16*, i16** [[TMP46]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = mul nuw i64 [[TMP34]], 2 +// CHECK1-NEXT: [[TMP49:%.*]] = udiv exact i64 [[TMP48]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP50:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP43]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = bitcast i8* [[TMP50]] to i64* +// CHECK1-NEXT: store i64 [[TMP49]], i64* [[TMP51]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP53:%.*]] = bitcast i16* [[TMP47]] to i8* +// CHECK1-NEXT: [[TMP54:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP52]], i8* [[TMP53]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP54]] to i16* +// CHECK1-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK1-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK1-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP47]] +// CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK1-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP57]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP49]] to i64 +// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP59]] to i64 // CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK1-NEXT: [[TMP50:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2 -// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP50]] to i32 -// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP51]], [[CONV5_I]] -// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4 -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP60:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6 +// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP60]] to i32 +// CHECK1-NEXT: [[TMP61:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP61]], [[CONV5_I]] +// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK1: .omp_outlined..9.exit: // CHECK1-NEXT: ret i32 0 @@ -1278,73 +1283,78 @@ // CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, i8***, i8***)* -// CHECK2-NEXT: call void [[TMP27]](i8* [[TMP26]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK2-NEXT: [[TMP28:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP28]], align 8 -// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP34:%.*]] = bitcast i32* [[TMP31]] to i8* -// CHECK2-NEXT: [[TMP35:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP32]], i8* [[TMP34]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP35]] to i32* -// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP37:%.*]] = load i16*, i16** [[TMP36]], align 8 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP24]], 2 -// CHECK2-NEXT: [[TMP39:%.*]] = udiv exact i64 [[TMP38]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP33]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK2-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to i64* -// CHECK2-NEXT: store i64 [[TMP39]], i64* [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP29]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = bitcast i16* [[TMP37]] to i8* -// CHECK2-NEXT: [[TMP44:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP42]], i8* [[TMP43]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP44]] to i16* -// CHECK2-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK2-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK2-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK2-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, i8***, i8***)* +// CHECK2-NEXT: call void [[TMP37]](i8* [[TMP36]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP38:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP44:%.*]] = bitcast i32* [[TMP41]] to i8* +// CHECK2-NEXT: [[TMP45:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP42]], i8* [[TMP44]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP45]] to i32* +// CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP47:%.*]] = load i16*, i16** [[TMP46]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = mul nuw i64 [[TMP34]], 2 +// CHECK2-NEXT: [[TMP49:%.*]] = udiv exact i64 [[TMP48]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP50:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP43]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = bitcast i8* [[TMP50]] to i64* +// CHECK2-NEXT: store i64 [[TMP49]], i64* [[TMP51]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP53:%.*]] = bitcast i16* [[TMP47]] to i8* +// CHECK2-NEXT: [[TMP54:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP52]], i8* [[TMP53]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP54]] to i16* +// CHECK2-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK2-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK2-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP47]] +// CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK2-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP57]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP49]] to i64 +// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP59]] to i64 // CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK2-NEXT: [[TMP50:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2 -// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP50]] to i32 -// CHECK2-NEXT: [[TMP51:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP51]], [[CONV5_I]] -// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4 -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP60:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6 +// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP60]] to i32 +// CHECK2-NEXT: [[TMP61:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP61]], [[CONV5_I]] +// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK2: .omp_outlined..9.exit: // CHECK2-NEXT: ret i32 0 Index: clang/test/OpenMP/master_taskloop_lastprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_lastprivate_codegen.cpp +++ clang/test/OpenMP/master_taskloop_lastprivate_codegen.cpp @@ -274,7 +274,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -443,7 +444,9 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], + // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/master_taskloop_private_codegen.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_private_codegen.cpp +++ clang/test/OpenMP/master_taskloop_private_codegen.cpp @@ -236,7 +236,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) @@ -365,7 +366,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/master_taskloop_simd_firstprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_simd_firstprivate_codegen.cpp +++ clang/test/OpenMP/master_taskloop_simd_firstprivate_codegen.cpp @@ -275,7 +275,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -426,7 +427,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp +++ clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp @@ -601,73 +601,78 @@ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, i8***, i8***)* -// CHECK1-NEXT: call void [[TMP27]](i8* [[TMP26]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP28]], align 8 -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP34:%.*]] = bitcast i32* [[TMP31]] to i8* -// CHECK1-NEXT: [[TMP35:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP32]], i8* [[TMP34]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP35]] to i32* -// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP37:%.*]] = load i16*, i16** [[TMP36]], align 8 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP24]], 2 -// CHECK1-NEXT: [[TMP39:%.*]] = udiv exact i64 [[TMP38]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP33]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK1-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to i64* -// CHECK1-NEXT: store i64 [[TMP39]], i64* [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP29]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = bitcast i16* [[TMP37]] to i8* -// CHECK1-NEXT: [[TMP44:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP42]], i8* [[TMP43]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP44]] to i16* -// CHECK1-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK1-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK1-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK1-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, i8***, i8***)* +// CHECK1-NEXT: call void [[TMP37]](i8* [[TMP36]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP38:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP44:%.*]] = bitcast i32* [[TMP41]] to i8* +// CHECK1-NEXT: [[TMP45:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP42]], i8* [[TMP44]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP45]] to i32* +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP47:%.*]] = load i16*, i16** [[TMP46]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = mul nuw i64 [[TMP34]], 2 +// CHECK1-NEXT: [[TMP49:%.*]] = udiv exact i64 [[TMP48]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP50:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP43]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = bitcast i8* [[TMP50]] to i64* +// CHECK1-NEXT: store i64 [[TMP49]], i64* [[TMP51]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP53:%.*]] = bitcast i16* [[TMP47]] to i8* +// CHECK1-NEXT: [[TMP54:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP52]], i8* [[TMP53]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP54]] to i16* +// CHECK1-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK1-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK1-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP47]] +// CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK1-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP57]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP49]] to i64 +// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP59]] to i64 // CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK1-NEXT: [[TMP50:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !llvm.access.group !15 -// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP50]] to i32 -// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP51]], [[CONV5_I]] -// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK1-NEXT: [[TMP60:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP60]] to i32 +// CHECK1-NEXT: [[TMP61:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP61]], [[CONV5_I]] +// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK1: .omp_outlined..9.exit: // CHECK1-NEXT: ret i32 0 @@ -1278,73 +1283,78 @@ // CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, i8***, i8***)* -// CHECK2-NEXT: call void [[TMP27]](i8* [[TMP26]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK2-NEXT: [[TMP28:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP28]], align 8 -// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP34:%.*]] = bitcast i32* [[TMP31]] to i8* -// CHECK2-NEXT: [[TMP35:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP32]], i8* [[TMP34]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP35]] to i32* -// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP37:%.*]] = load i16*, i16** [[TMP36]], align 8 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP24]], 2 -// CHECK2-NEXT: [[TMP39:%.*]] = udiv exact i64 [[TMP38]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP33]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK2-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to i64* -// CHECK2-NEXT: store i64 [[TMP39]], i64* [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP29]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = bitcast i16* [[TMP37]] to i8* -// CHECK2-NEXT: [[TMP44:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP42]], i8* [[TMP43]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP44]] to i16* -// CHECK2-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK2-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK2-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK2-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, i8***, i8***)* +// CHECK2-NEXT: call void [[TMP37]](i8* [[TMP36]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP38:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP44:%.*]] = bitcast i32* [[TMP41]] to i8* +// CHECK2-NEXT: [[TMP45:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP42]], i8* [[TMP44]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP45]] to i32* +// CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP47:%.*]] = load i16*, i16** [[TMP46]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = mul nuw i64 [[TMP34]], 2 +// CHECK2-NEXT: [[TMP49:%.*]] = udiv exact i64 [[TMP48]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP50:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP43]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = bitcast i8* [[TMP50]] to i64* +// CHECK2-NEXT: store i64 [[TMP49]], i64* [[TMP51]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP53:%.*]] = bitcast i16* [[TMP47]] to i8* +// CHECK2-NEXT: [[TMP54:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP52]], i8* [[TMP53]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP54]] to i16* +// CHECK2-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK2-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK2-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP47]] +// CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK2-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP57]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP49]] to i64 +// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP59]] to i64 // CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK2-NEXT: [[TMP50:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !llvm.access.group !15 -// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP50]] to i32 -// CHECK2-NEXT: [[TMP51:%.*]] = load i32, i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP51]], [[CONV5_I]] -// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK2-NEXT: [[TMP60:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP60]] to i32 +// CHECK2-NEXT: [[TMP61:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP61]], [[CONV5_I]] +// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK2: .omp_outlined..9.exit: // CHECK2-NEXT: ret i32 0 Index: clang/test/OpenMP/master_taskloop_simd_lastprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_simd_lastprivate_codegen.cpp +++ clang/test/OpenMP/master_taskloop_simd_lastprivate_codegen.cpp @@ -265,7 +265,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -434,7 +435,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/master_taskloop_simd_private_codegen.cpp =================================================================== --- clang/test/OpenMP/master_taskloop_simd_private_codegen.cpp +++ clang/test/OpenMP/master_taskloop_simd_private_codegen.cpp @@ -229,7 +229,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) @@ -358,7 +359,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp =================================================================== --- clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp +++ clang/test/OpenMP/nvptx_target_parallel_reduction_codegen_tbaa_PR46146.cpp @@ -42,7 +42,7 @@ // CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK1-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK1-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA8:![0-9]+]] -// CHECK1-NEXT: call void @__omp_outlined__(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR5:[0-9]+]] +// CHECK1-NEXT: call void @__omp_outlined__(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR6:[0-9]+]] // CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true) // CHECK1-NEXT: ret void // CHECK1: worker.exit: @@ -64,112 +64,114 @@ // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca float, align 4 // CHECK1-NEXT: [[REF_TMP2:%.*]] = alloca float, align 4 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [3 x i8*], align 8 -// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12:![0-9]+]] -// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META17:![0-9]+]]) +// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ISTART:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK1-NEXT: [[ISTART_ON_STACK:%.*]] = bitcast i8* [[ISTART]] to i32* // CHECK1-NEXT: [[IEND:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK1-NEXT: [[IEND_ON_STACK:%.*]] = bitcast i8* [[IEND]] to i32* // CHECK1-NEXT: [[PARTIAL_SUM:%.*]] = call i8* @__kmpc_alloc_shared(i64 8) // CHECK1-NEXT: [[PARTIAL_SUM_ON_STACK:%.*]] = bitcast i8* [[PARTIAL_SUM]] to %"class.std::complex"* -// CHECK1-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP1]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR6]] // CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR6]] // CHECK1-NEXT: store i32 99, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] // CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] // CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP7]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 99 +// CHECK1-NEXT: [[TMP7:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP7]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP9]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 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: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP9]], [[COND_FALSE]] ] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ] // CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP10]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP12]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] // CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK1: omp.inner.for.cond.cleanup: // CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP13]], 1 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP15]], 1 // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] // CHECK1-NEXT: store i32 [[ADD]], i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP14:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP14]]) #[[ATTR5]] -// CHECK1-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA14:![0-9]+]] -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast float* [[REF_TMP2]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP15]]) #[[ATTR5]] -// CHECK1-NEXT: store float 0.000000e+00, float* [[REF_TMP2]], align 4, !tbaa [[TBAA14]] -// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM_ON_STACK]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR11:[0-9]+]] -// CHECK1-NEXT: [[TMP16:%.*]] = bitcast float* [[REF_TMP2]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP18]], 4 +// CHECK1-NEXT: [[TMP16:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR6]] +// CHECK1-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA19:![0-9]+]] +// CHECK1-NEXT: [[TMP17:%.*]] = bitcast float* [[REF_TMP2]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR6]] +// CHECK1-NEXT: store float 0.000000e+00, float* [[REF_TMP2]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM_ON_STACK]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR13:[0-9]+]] +// CHECK1-NEXT: [[TMP18:%.*]] = bitcast float* [[REF_TMP2]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP18]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP19:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP20]], 4 // CHECK1-NEXT: store i32 [[MUL3]], i32* [[ISTART_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK1-NEXT: [[MUL5:%.*]] = mul nsw i32 [[ADD4]], 4 // CHECK1-NEXT: store i32 [[MUL5]], i32* [[IEND_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 -// CHECK1-NEXT: [[TMP23:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* -// CHECK1-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 -// CHECK1-NEXT: [[TMP25:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM_ON_STACK]] to i8* -// CHECK1-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP26:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP7]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex"*)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** [[TMP26]], i64 3) +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 +// CHECK1-NEXT: [[TMP25:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 +// CHECK1-NEXT: [[TMP27:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM_ON_STACK]] to i8* +// CHECK1-NEXT: store i8* [[TMP27]], i8** [[TMP26]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP28:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP9]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex"*)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** [[TMP28]], i64 3) // 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: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP27]], 1 +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP29]], 1 // CHECK1-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]]) -// CHECK1-NEXT: [[TMP28:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP29]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP30:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR5]] +// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP9]]) +// CHECK1-NEXT: [[TMP30:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP34:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP34]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP35:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP35]]) #[[ATTR6]] // CHECK1-NEXT: call void @__kmpc_free_shared(i8* [[PARTIAL_SUM]], i64 8) // CHECK1-NEXT: call void @__kmpc_free_shared(i8* [[IEND]], i64 4) // CHECK1-NEXT: call void @__kmpc_free_shared(i8* [[ISTART]], i64 4) @@ -177,18 +179,18 @@ // // // CHECK1-LABEL: define {{[^@]+}}@_ZNSt7complexIfEC1ERKfS2_ -// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR3:[0-9]+]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR4:[0-9]+]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 // CHECK1-NEXT: [[__RE_ADDR:%.*]] = alloca float*, align 8 // CHECK1-NEXT: [[__IM_ADDR:%.*]] = alloca float*, align 8 -// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8 // CHECK1-NEXT: [[TMP1:%.*]] = load float*, float** [[__IM_ADDR]], align 8 -// CHECK1-NEXT: call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR11]] +// CHECK1-NEXT: call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR13]] // CHECK1-NEXT: ret void // // @@ -218,224 +220,226 @@ // CHECK1-NEXT: [[REF_TMP15:%.*]] = alloca float, align 4 // CHECK1-NEXT: [[REF_TMP16:%.*]] = alloca float, align 4 // CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 -// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store %"class.std::complex"* [[PARTIAL_SUM]], %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP0]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP5]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP9]], [[TMP10]] +// CHECK1-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META21:![0-9]+]]) +// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META24:![0-9]+]]) +// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store %"class.std::complex"* [[PARTIAL_SUM]], %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP4:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP2]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP9]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP10:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP10]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP11]], [[TMP12]] // CHECK1-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 // CHECK1-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 1 // CHECK1-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 1 // CHECK1-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 // CHECK1-NEXT: store i32 [[SUB4]], i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i32* [[I]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP11]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP12]], i32* [[I]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: [[TMP13:%.*]] = bitcast i32* [[I]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR5]] +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR6]] // CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP14]], [[TMP15]] +// CHECK1-NEXT: store i32 [[TMP14]], i32* [[I]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP15:%.*]] = bitcast i32* [[I]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP15]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP16]], [[TMP17]] // CHECK1-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] // CHECK1: omp.precond.then: -// CHECK1-NEXT: [[TMP16:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP18:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP18]]) #[[ATTR6]] // CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP18]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP21]]) #[[ATTR6]] // CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP20]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP22:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP22]]) #[[ATTR6]] // CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP22:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP22]]) #[[ATTR5]] -// CHECK1-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA14]] -// CHECK1-NEXT: [[TMP23:%.*]] = bitcast float* [[REF_TMP6]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP23]]) #[[ATTR5]] -// CHECK1-NEXT: store float 0.000000e+00, float* [[REF_TMP6]], align 4, !tbaa [[TBAA14]] -// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR11]] -// CHECK1-NEXT: [[TMP24:%.*]] = bitcast float* [[REF_TMP6]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP24]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP25:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP26:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP26]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP28]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP23]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP24:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP24]]) #[[ATTR6]] +// CHECK1-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: [[TMP25:%.*]] = bitcast float* [[REF_TMP6]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP25]]) #[[ATTR6]] +// CHECK1-NEXT: store float 0.000000e+00, float* [[REF_TMP6]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR13]] +// CHECK1-NEXT: [[TMP26:%.*]] = bitcast float* [[REF_TMP6]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP26]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP27:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP27]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP28:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP30]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP29]], [[TMP30]] +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP31]], [[TMP32]] // CHECK1-NEXT: br i1 [[CMP8]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK1: cond.true: -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[COND_END:%.*]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[TMP31]], [[COND_TRUE]] ], [ [[TMP32]], [[COND_FALSE]] ] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[TMP33]], [[COND_TRUE]] ], [ [[TMP34]], [[COND_FALSE]] ] // CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP33]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD9:%.*]] = add i32 [[TMP35]], 1 -// CHECK1-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP34]], [[ADD9]] +// CHECK1-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP35]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD9:%.*]] = add i32 [[TMP37]], 1 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP36]], [[ADD9]] // CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_CLEANUP:%.*]] // CHECK1: omp.dispatch.cleanup: // CHECK1-NEXT: br label [[OMP_DISPATCH_END:%.*]] // CHECK1: omp.dispatch.body: // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD11:%.*]] = add i32 [[TMP37]], 1 -// CHECK1-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP36]], [[ADD11]] +// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD11:%.*]] = add i32 [[TMP39]], 1 +// CHECK1-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP38]], [[ADD11]] // CHECK1-NEXT: br i1 [[CMP12]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK1: omp.inner.for.cond.cleanup: // CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP39]], 1 -// CHECK1-NEXT: [[ADD13:%.*]] = add i32 [[TMP38]], [[MUL]] +// CHECK1-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP41]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add i32 [[TMP40]], [[MUL]] // CHECK1-NEXT: store i32 [[ADD13]], i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP40:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP40]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = bitcast float* [[REF_TMP15]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP41]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP42:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP42]] to float -// CHECK1-NEXT: store float [[CONV]], float* [[REF_TMP15]], align 4, !tbaa [[TBAA14]] -// CHECK1-NEXT: [[TMP43:%.*]] = bitcast float* [[REF_TMP16]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP43]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP42:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP42]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP43:%.*]] = bitcast float* [[REF_TMP15]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP43]]) #[[ATTR6]] // CHECK1-NEXT: [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP44]] to float -// CHECK1-NEXT: store float [[CONV17]], float* [[REF_TMP16]], align 4, !tbaa [[TBAA14]] -// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR11]] -// CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR11]] +// CHECK1-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP44]] to float +// CHECK1-NEXT: store float [[CONV]], float* [[REF_TMP15]], align 4, !tbaa [[TBAA19]] // CHECK1-NEXT: [[TMP45:%.*]] = bitcast float* [[REF_TMP16]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP45]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP46:%.*]] = bitcast float* [[REF_TMP15]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP46]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP47:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP47]]) #[[ATTR5]] +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP45]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP46]] to float +// CHECK1-NEXT: store float [[CONV17]], float* [[REF_TMP16]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR13]] +// CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR13]] +// CHECK1-NEXT: [[TMP47:%.*]] = bitcast float* [[REF_TMP16]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP47]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP48:%.*]] = bitcast float* [[REF_TMP15]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP48]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP49:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP49]]) #[[ATTR6]] // 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: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD18:%.*]] = add i32 [[TMP48]], 1 +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD18:%.*]] = add i32 [[TMP50]], 1 // CHECK1-NEXT: store i32 [[ADD18]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD19:%.*]] = add i32 [[TMP49]], [[TMP50]] -// CHECK1-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD20:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK1-NEXT: [[ADD19:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK1-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD20:%.*]] = add i32 [[TMP53]], [[TMP54]] // CHECK1-NEXT: store i32 [[ADD20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: [[TMP53:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP54]]) // CHECK1-NEXT: [[TMP55:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP55]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP57:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP58:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* -// CHECK1-NEXT: store i8* [[TMP58]], i8** [[TMP57]], align 8 -// CHECK1-NEXT: [[TMP59:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* -// CHECK1-NEXT: [[TMP60:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP56]], i32 1, i64 8, i8* [[TMP59]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func) -// CHECK1-NEXT: [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1 -// CHECK1-NEXT: br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP56]]) +// CHECK1-NEXT: [[TMP57:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[TMP57]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP60:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* +// CHECK1-NEXT: store i8* [[TMP60]], i8** [[TMP59]], align 8 +// CHECK1-NEXT: [[TMP61:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* +// CHECK1-NEXT: [[TMP62:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP58]], i32 1, i64 8, i8* [[TMP61]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func) +// CHECK1-NEXT: [[TMP63:%.*]] = icmp eq i32 [[TMP62]], 1 +// CHECK1-NEXT: br i1 [[TMP63]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] // CHECK1: .omp.reduction.then: -// CHECK1-NEXT: [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR11]] -// CHECK1-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]]) +// CHECK1-NEXT: [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP4]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR13]] +// CHECK1-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP58]]) // CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DONE]] // CHECK1: .omp.reduction.done: -// CHECK1-NEXT: [[TMP62:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP63:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP63]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP64:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP65:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP65]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR6]] // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: -// CHECK1-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP72:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP73:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR6]] // CHECK1-NEXT: ret void // // // CHECK1-LABEL: define {{[^@]+}}@_ZNSt7complexIfEpLIfEERS0_RKS_IT_E -// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[__C:%.*]]) #[[ATTR4:[0-9]+]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[__C:%.*]]) #[[ATTR5:[0-9]+]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 // CHECK1-NEXT: [[__C_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 -// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store %"class.std::complex"* [[__C]], %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store %"class.std::complex"* [[__C]], %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 -// CHECK1-NEXT: [[TMP0:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP0]]) #[[ATTR11]] +// CHECK1-NEXT: [[TMP0:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP0]]) #[[ATTR13]] // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA16:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA26:![0-9]+]] // CHECK1-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[CALL]] -// CHECK1-NEXT: store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA16]] -// CHECK1-NEXT: [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]]) #[[ATTR11]] +// CHECK1-NEXT: store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA26]] +// CHECK1-NEXT: [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]]) #[[ATTR13]] // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA18:![0-9]+]] +// CHECK1-NEXT: [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA28:![0-9]+]] // CHECK1-NEXT: [[ADD3:%.*]] = fadd float [[TMP3]], [[CALL2]] -// CHECK1-NEXT: store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA18]] +// CHECK1-NEXT: store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK1-NEXT: ret %"class.std::complex"* [[THIS1]] // // // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func -// CHECK1-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR6:[0-9]+]] { +// CHECK1-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR7:[0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i16, align 2 @@ -443,15 +447,15 @@ // CHECK1-NEXT: [[DOTADDR3:%.*]] = alloca i16, align 2 // CHECK1-NEXT: [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST:%.*]] = alloca [1 x i8*], align 8 // CHECK1-NEXT: [[DOTOMP_REDUCTION_ELEMENT:%.*]] = alloca %"class.std::complex", align 4 -// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19:![0-9]+]] -// CHECK1-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK1-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29:![0-9]+]] +// CHECK1-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]* -// CHECK1-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0 // CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]], i64 0, i64 0 @@ -468,7 +472,7 @@ // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr i64, i64* [[TMP15]], i64 1 // CHECK1-NEXT: [[TMP21:%.*]] = getelementptr i64, i64* [[TMP16]], i64 1 // CHECK1-NEXT: [[TMP22:%.*]] = bitcast %"class.std::complex"* [[DOTOMP_REDUCTION_ELEMENT]] to i8* -// CHECK1-NEXT: store i8* [[TMP22]], i8** [[TMP11]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store i8* [[TMP22]], i8** [[TMP11]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP23:%.*]] = icmp eq i16 [[TMP8]], 0 // CHECK1-NEXT: [[TMP24:%.*]] = icmp eq i16 [[TMP8]], 1 // CHECK1-NEXT: [[TMP25:%.*]] = icmp ult i16 [[TMP6]], [[TMP7]] @@ -485,7 +489,7 @@ // CHECK1: then: // CHECK1-NEXT: [[TMP35:%.*]] = bitcast [1 x i8*]* [[TMP5]] to i8* // CHECK1-NEXT: [[TMP36:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]] to i8* -// CHECK1-NEXT: call void @"_omp$reduction$reduction_func"(i8* [[TMP35]], i8* [[TMP36]]) #[[ATTR5]] +// CHECK1-NEXT: call void @"_omp$reduction$reduction_func"(i8* [[TMP35]], i8* [[TMP36]]) #[[ATTR6]] // CHECK1-NEXT: br label [[IFCONT:%.*]] // CHECK1: else: // CHECK1-NEXT: br label [[IFCONT]] @@ -503,7 +507,7 @@ // CHECK1-NEXT: [[TMP45:%.*]] = bitcast i8* [[TMP43]] to %"class.std::complex"* // CHECK1-NEXT: [[TMP46:%.*]] = bitcast %"class.std::complex"* [[TMP45]] to i8* // CHECK1-NEXT: [[TMP47:%.*]] = bitcast %"class.std::complex"* [[TMP44]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !21 +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !31 // CHECK1-NEXT: br label [[IFCONT6:%.*]] // CHECK1: else5: // CHECK1-NEXT: br label [[IFCONT6]] @@ -512,13 +516,13 @@ // // // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_inter_warp_copy_func -// CHECK1-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK1-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTCNT_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) -// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: [[NVPTX_TID:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() // CHECK1-NEXT: [[NVPTX_TID2:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() @@ -539,7 +543,7 @@ // CHECK1-NEXT: br i1 [[WARP_MASTER]], label [[THEN:%.*]], label [[ELSE:%.*]] // CHECK1: then: // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP9:%.*]] = bitcast i8* [[TMP8]] to i32* // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr i32, i32* [[TMP9]], i32 [[TMP5]] // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] @@ -556,7 +560,7 @@ // CHECK1: then2: // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_TID]] // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to i32* // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr i32, i32* [[TMP17]], i32 [[TMP5]] // CHECK1-NEXT: [[TMP19:%.*]] = load volatile i32, i32 addrspace(3)* [[TMP14]], align 4, !tbaa [[TBAA8]] @@ -573,27 +577,27 @@ // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper -// CHECK1-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK1-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8 -// CHECK1-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA19]] +// CHECK1-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA29]] // CHECK1-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK1-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) // CHECK1-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8 // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32** -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 1 // CHECK1-NEXT: [[TMP7:%.*]] = bitcast i8** [[TMP6]] to i32** -// CHECK1-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 2 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast i8** [[TMP9]] to %"class.std::complex"** -// CHECK1-NEXT: [[TMP11:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[TMP10]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex"* [[TMP11]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP11:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[TMP10]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex"* [[TMP11]]) #[[ATTR6]] // CHECK1-NEXT: ret void // // @@ -609,7 +613,7 @@ // CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK1-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK1-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: call void @__omp_outlined__2(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR5]] +// CHECK1-NEXT: call void @__omp_outlined__2(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR6]] // CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true) // CHECK1-NEXT: ret void // CHECK1: worker.exit: @@ -631,112 +635,114 @@ // CHECK1-NEXT: [[REF_TMP:%.*]] = alloca double, align 8 // CHECK1-NEXT: [[REF_TMP2:%.*]] = alloca double, align 8 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [3 x i8*], align 8 -// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META32:![0-9]+]]) +// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META35:![0-9]+]]) +// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[ISTART:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK1-NEXT: [[ISTART_ON_STACK:%.*]] = bitcast i8* [[ISTART]] to i32* // CHECK1-NEXT: [[IEND:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK1-NEXT: [[IEND_ON_STACK:%.*]] = bitcast i8* [[IEND]] to i32* // CHECK1-NEXT: [[PARTIAL_SUM:%.*]] = call i8* @__kmpc_alloc_shared(i64 16) // CHECK1-NEXT: [[PARTIAL_SUM_ON_STACK:%.*]] = bitcast i8* [[PARTIAL_SUM]] to %"class.std::complex.0"* -// CHECK1-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP1]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR6]] // CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR6]] // CHECK1-NEXT: store i32 99, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] // CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] // CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 99 +// CHECK1-NEXT: [[TMP7:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP7]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP9]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 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: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP9]], [[COND_FALSE]] ] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ] // CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP10]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP12]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] // CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK1: omp.inner.for.cond.cleanup: // CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP13]], 1 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP15]], 1 // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] // CHECK1-NEXT: store i32 [[ADD]], i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP14:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP14]]) #[[ATTR5]] -// CHECK1-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA22:![0-9]+]] -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast double* [[REF_TMP2]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP15]]) #[[ATTR5]] -// CHECK1-NEXT: store double 0.000000e+00, double* [[REF_TMP2]], align 8, !tbaa [[TBAA22]] -// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM_ON_STACK]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR11]] -// CHECK1-NEXT: [[TMP16:%.*]] = bitcast double* [[REF_TMP2]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP16]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP17]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP18]], 4 +// CHECK1-NEXT: [[TMP16:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP16]]) #[[ATTR6]] +// CHECK1-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA37:![0-9]+]] +// CHECK1-NEXT: [[TMP17:%.*]] = bitcast double* [[REF_TMP2]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP17]]) #[[ATTR6]] +// CHECK1-NEXT: store double 0.000000e+00, double* [[REF_TMP2]], align 8, !tbaa [[TBAA37]] +// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM_ON_STACK]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR13]] +// CHECK1-NEXT: [[TMP18:%.*]] = bitcast double* [[REF_TMP2]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP18]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP19:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP19]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP20]], 4 // CHECK1-NEXT: store i32 [[MUL3]], i32* [[ISTART_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK1-NEXT: [[MUL5:%.*]] = mul nsw i32 [[ADD4]], 4 // CHECK1-NEXT: store i32 [[MUL5]], i32* [[IEND_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 -// CHECK1-NEXT: [[TMP23:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* -// CHECK1-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 -// CHECK1-NEXT: [[TMP25:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM_ON_STACK]] to i8* -// CHECK1-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP26:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP7]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex.0"*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP26]], i64 3) +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 +// CHECK1-NEXT: [[TMP25:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 +// CHECK1-NEXT: [[TMP27:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM_ON_STACK]] to i8* +// CHECK1-NEXT: store i8* [[TMP27]], i8** [[TMP26]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP28:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP9]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex.0"*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP28]], i64 3) // 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: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP27]], 1 +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP29]], 1 // CHECK1-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: -// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]]) -// CHECK1-NEXT: [[TMP28:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP29]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP30:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR5]] +// CHECK1-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP9]]) +// CHECK1-NEXT: [[TMP30:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP34:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP34]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP35:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP35]]) #[[ATTR6]] // CHECK1-NEXT: call void @__kmpc_free_shared(i8* [[PARTIAL_SUM]], i64 16) // CHECK1-NEXT: call void @__kmpc_free_shared(i8* [[IEND]], i64 4) // CHECK1-NEXT: call void @__kmpc_free_shared(i8* [[ISTART]], i64 4) @@ -744,18 +750,18 @@ // // // CHECK1-LABEL: define {{[^@]+}}@_ZNSt7complexIdEC1ERKdS2_ -// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 // CHECK1-NEXT: [[__RE_ADDR:%.*]] = alloca double*, align 8 // CHECK1-NEXT: [[__IM_ADDR:%.*]] = alloca double*, align 8 -// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8 // CHECK1-NEXT: [[TMP1:%.*]] = load double*, double** [[__IM_ADDR]], align 8 -// CHECK1-NEXT: call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR11]] +// CHECK1-NEXT: call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR13]] // CHECK1-NEXT: ret void // // @@ -785,224 +791,226 @@ // CHECK1-NEXT: [[REF_TMP15:%.*]] = alloca double, align 8 // CHECK1-NEXT: [[REF_TMP16:%.*]] = alloca double, align 8 // CHECK1-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 -// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store %"class.std::complex.0"* [[PARTIAL_SUM]], %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP0:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP2:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP0]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP5]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP9]], [[TMP10]] +// CHECK1-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META39:![0-9]+]]) +// CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META42:![0-9]+]]) +// CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store %"class.std::complex.0"* [[PARTIAL_SUM]], %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP4:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP2]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP9]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP10:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP10]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[SUB:%.*]] = sub i32 [[TMP11]], [[TMP12]] // CHECK1-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 // CHECK1-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 1 // CHECK1-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 1 // CHECK1-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 // CHECK1-NEXT: store i32 [[SUB4]], i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP11:%.*]] = bitcast i32* [[I]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP11]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP12]], i32* [[I]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: [[TMP13:%.*]] = bitcast i32* [[I]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR5]] +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR6]] // CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP14]], [[TMP15]] +// CHECK1-NEXT: store i32 [[TMP14]], i32* [[I]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP15:%.*]] = bitcast i32* [[I]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP15]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP16]], [[TMP17]] // CHECK1-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] // CHECK1: omp.precond.then: -// CHECK1-NEXT: [[TMP16:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP18:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP18]]) #[[ATTR6]] // CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP18]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP21]]) #[[ATTR6]] // CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP20:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP20]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP22:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP22]]) #[[ATTR6]] // CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP22:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP22]]) #[[ATTR5]] -// CHECK1-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA22]] -// CHECK1-NEXT: [[TMP23:%.*]] = bitcast double* [[REF_TMP6]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP23]]) #[[ATTR5]] -// CHECK1-NEXT: store double 0.000000e+00, double* [[REF_TMP6]], align 8, !tbaa [[TBAA22]] -// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR11]] -// CHECK1-NEXT: [[TMP24:%.*]] = bitcast double* [[REF_TMP6]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP24]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP25:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP26:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP26]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3]], i32 [[TMP28]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP23]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP24:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP24]]) #[[ATTR6]] +// CHECK1-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA37]] +// CHECK1-NEXT: [[TMP25:%.*]] = bitcast double* [[REF_TMP6]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP25]]) #[[ATTR6]] +// CHECK1-NEXT: store double 0.000000e+00, double* [[REF_TMP6]], align 8, !tbaa [[TBAA37]] +// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR13]] +// CHECK1-NEXT: [[TMP26:%.*]] = bitcast double* [[REF_TMP6]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP26]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP27:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP27]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP28:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP29]], [[TMP30]] +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP31]], [[TMP32]] // CHECK1-NEXT: br i1 [[CMP8]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK1: cond.true: -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[COND_END:%.*]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[COND_END]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[TMP31]], [[COND_TRUE]] ], [ [[TMP32]], [[COND_FALSE]] ] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ [[TMP33]], [[COND_TRUE]] ], [ [[TMP34]], [[COND_FALSE]] ] // CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: store i32 [[TMP33]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD9:%.*]] = add i32 [[TMP35]], 1 -// CHECK1-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP34]], [[ADD9]] +// CHECK1-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: store i32 [[TMP35]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD9:%.*]] = add i32 [[TMP37]], 1 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP36]], [[ADD9]] // CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_CLEANUP:%.*]] // CHECK1: omp.dispatch.cleanup: // CHECK1-NEXT: br label [[OMP_DISPATCH_END:%.*]] // CHECK1: omp.dispatch.body: // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD11:%.*]] = add i32 [[TMP37]], 1 -// CHECK1-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP36]], [[ADD11]] +// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD11:%.*]] = add i32 [[TMP39]], 1 +// CHECK1-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP38]], [[ADD11]] // CHECK1-NEXT: br i1 [[CMP12]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK1: omp.inner.for.cond.cleanup: // CHECK1-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP39]], 1 -// CHECK1-NEXT: [[ADD13:%.*]] = add i32 [[TMP38]], [[MUL]] +// CHECK1-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[MUL:%.*]] = mul i32 [[TMP41]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add i32 [[TMP40]], [[MUL]] // CHECK1-NEXT: store i32 [[ADD13]], i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP40:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP40]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = bitcast double* [[REF_TMP15]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP41]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP42:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP42]] to double -// CHECK1-NEXT: store double [[CONV]], double* [[REF_TMP15]], align 8, !tbaa [[TBAA22]] -// CHECK1-NEXT: [[TMP43:%.*]] = bitcast double* [[REF_TMP16]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP43]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP42:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP42]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP43:%.*]] = bitcast double* [[REF_TMP15]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP43]]) #[[ATTR6]] // CHECK1-NEXT: [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP44]] to double -// CHECK1-NEXT: store double [[CONV17]], double* [[REF_TMP16]], align 8, !tbaa [[TBAA22]] -// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR11]] -// CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR11]] +// CHECK1-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP44]] to double +// CHECK1-NEXT: store double [[CONV]], double* [[REF_TMP15]], align 8, !tbaa [[TBAA37]] // CHECK1-NEXT: [[TMP45:%.*]] = bitcast double* [[REF_TMP16]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP45]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP46:%.*]] = bitcast double* [[REF_TMP15]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP46]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP47:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP47]]) #[[ATTR5]] +// CHECK1-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP45]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP46]] to double +// CHECK1-NEXT: store double [[CONV17]], double* [[REF_TMP16]], align 8, !tbaa [[TBAA37]] +// CHECK1-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR13]] +// CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR13]] +// CHECK1-NEXT: [[TMP47:%.*]] = bitcast double* [[REF_TMP16]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP47]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP48:%.*]] = bitcast double* [[REF_TMP15]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP48]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP49:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP49]]) #[[ATTR6]] // 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: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD18:%.*]] = add i32 [[TMP48]], 1 +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD18:%.*]] = add i32 [[TMP50]], 1 // CHECK1-NEXT: store i32 [[ADD18]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD19:%.*]] = add i32 [[TMP49]], [[TMP50]] -// CHECK1-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[ADD20:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK1-NEXT: [[ADD19:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK1-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[ADD20:%.*]] = add i32 [[TMP53]], [[TMP54]] // CHECK1-NEXT: store i32 [[ADD20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: [[TMP53:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP54]]) // CHECK1-NEXT: [[TMP55:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP55]], align 4, !tbaa [[TBAA8]] -// CHECK1-NEXT: [[TMP57:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP58:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* -// CHECK1-NEXT: store i8* [[TMP58]], i8** [[TMP57]], align 8 -// CHECK1-NEXT: [[TMP59:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* -// CHECK1-NEXT: [[TMP60:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP56]], i32 1, i64 8, i8* [[TMP59]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func5, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func6) -// CHECK1-NEXT: [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1 -// CHECK1-NEXT: br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP56]]) +// CHECK1-NEXT: [[TMP57:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[TMP57]], align 4, !tbaa [[TBAA8]] +// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP60:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* +// CHECK1-NEXT: store i8* [[TMP60]], i8** [[TMP59]], align 8 +// CHECK1-NEXT: [[TMP61:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* +// CHECK1-NEXT: [[TMP62:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP58]], i32 1, i64 8, i8* [[TMP61]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func5, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func6) +// CHECK1-NEXT: [[TMP63:%.*]] = icmp eq i32 [[TMP62]], 1 +// CHECK1-NEXT: br i1 [[TMP63]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] // CHECK1: .omp.reduction.then: -// CHECK1-NEXT: [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP2]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR11]] -// CHECK1-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]]) +// CHECK1-NEXT: [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP4]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR13]] +// CHECK1-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP58]]) // CHECK1-NEXT: br label [[DOTOMP_REDUCTION_DONE]] // CHECK1: .omp.reduction.done: -// CHECK1-NEXT: [[TMP62:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP63:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP63]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP64:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP65:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP65]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR6]] // CHECK1-NEXT: br label [[OMP_PRECOND_END]] // CHECK1: omp.precond.end: -// CHECK1-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP72:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR6]] +// CHECK1-NEXT: [[TMP73:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK1-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR6]] // CHECK1-NEXT: ret void // // // CHECK1-LABEL: define {{[^@]+}}@_ZNSt7complexIdEpLIdEERS0_RKS_IT_E -// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[__C:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[__C:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 // CHECK1-NEXT: [[__C_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 -// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store %"class.std::complex.0"* [[__C]], %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store %"class.std::complex.0"* [[__C]], %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 -// CHECK1-NEXT: [[TMP0:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP0]]) #[[ATTR11]] +// CHECK1-NEXT: [[TMP0:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP0]]) #[[ATTR13]] // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA44:![0-9]+]] // CHECK1-NEXT: [[ADD:%.*]] = fadd double [[TMP1]], [[CALL]] -// CHECK1-NEXT: store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA24]] -// CHECK1-NEXT: [[TMP2:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP2]]) #[[ATTR11]] +// CHECK1-NEXT: store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA44]] +// CHECK1-NEXT: [[TMP2:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP2]]) #[[ATTR13]] // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26:![0-9]+]] +// CHECK1-NEXT: [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA46:![0-9]+]] // CHECK1-NEXT: [[ADD3:%.*]] = fadd double [[TMP3]], [[CALL2]] -// CHECK1-NEXT: store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]] +// CHECK1-NEXT: store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA46]] // CHECK1-NEXT: ret %"class.std::complex.0"* [[THIS1]] // // // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func5 -// CHECK1-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR6]] { +// CHECK1-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR7]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i16, align 2 @@ -1010,15 +1018,15 @@ // CHECK1-NEXT: [[DOTADDR3:%.*]] = alloca i16, align 2 // CHECK1-NEXT: [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST:%.*]] = alloca [1 x i8*], align 8 // CHECK1-NEXT: [[DOTOMP_REDUCTION_ELEMENT:%.*]] = alloca %"class.std::complex.0", align 8 -// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19]] -// CHECK1-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK1-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]* -// CHECK1-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0 // CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8 // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]], i64 0, i64 0 @@ -1049,7 +1057,7 @@ // CHECK1-NEXT: br label [[DOTSHUFFLE_PRE_COND]] // CHECK1: .shuffle.exit: // CHECK1-NEXT: [[TMP30:%.*]] = bitcast %"class.std::complex.0"* [[DOTOMP_REDUCTION_ELEMENT]] to i8* -// CHECK1-NEXT: store i8* [[TMP30]], i8** [[TMP11]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store i8* [[TMP30]], i8** [[TMP11]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP31:%.*]] = icmp eq i16 [[TMP8]], 0 // CHECK1-NEXT: [[TMP32:%.*]] = icmp eq i16 [[TMP8]], 1 // CHECK1-NEXT: [[TMP33:%.*]] = icmp ult i16 [[TMP6]], [[TMP7]] @@ -1066,7 +1074,7 @@ // CHECK1: then: // CHECK1-NEXT: [[TMP43:%.*]] = bitcast [1 x i8*]* [[TMP5]] to i8* // CHECK1-NEXT: [[TMP44:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]] to i8* -// CHECK1-NEXT: call void @"_omp$reduction$reduction_func4"(i8* [[TMP43]], i8* [[TMP44]]) #[[ATTR5]] +// CHECK1-NEXT: call void @"_omp$reduction$reduction_func4"(i8* [[TMP43]], i8* [[TMP44]]) #[[ATTR6]] // CHECK1-NEXT: br label [[IFCONT:%.*]] // CHECK1: else: // CHECK1-NEXT: br label [[IFCONT]] @@ -1084,7 +1092,7 @@ // CHECK1-NEXT: [[TMP53:%.*]] = bitcast i8* [[TMP51]] to %"class.std::complex.0"* // CHECK1-NEXT: [[TMP54:%.*]] = bitcast %"class.std::complex.0"* [[TMP53]] to i8* // CHECK1-NEXT: [[TMP55:%.*]] = bitcast %"class.std::complex.0"* [[TMP52]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !27 +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !47 // CHECK1-NEXT: br label [[IFCONT6:%.*]] // CHECK1: else5: // CHECK1-NEXT: br label [[IFCONT6]] @@ -1093,13 +1101,13 @@ // // // CHECK1-LABEL: define {{[^@]+}}@_omp_reduction_inter_warp_copy_func6 -// CHECK1-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK1-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTCNT_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) -// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: [[NVPTX_TID:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() // CHECK1-NEXT: [[NVPTX_TID2:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() @@ -1120,7 +1128,7 @@ // CHECK1-NEXT: br i1 [[WARP_MASTER]], label [[THEN:%.*]], label [[ELSE:%.*]] // CHECK1: then: // CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP9:%.*]] = bitcast i8* [[TMP8]] to i32* // CHECK1-NEXT: [[TMP10:%.*]] = getelementptr i32, i32* [[TMP9]], i32 [[TMP5]] // CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] @@ -1137,7 +1145,7 @@ // CHECK1: then2: // CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_TID]] // CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to i32* // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr i32, i32* [[TMP17]], i32 [[TMP5]] // CHECK1-NEXT: [[TMP19:%.*]] = load volatile i32, i32 addrspace(3)* [[TMP14]], align 4, !tbaa [[TBAA8]] @@ -1154,113 +1162,113 @@ // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__3_wrapper -// CHECK1-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK1-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 // CHECK1-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK1-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8 -// CHECK1-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA19]] +// CHECK1-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA29]] // CHECK1-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK1-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK1-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) // CHECK1-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8 // CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0 // CHECK1-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32** -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 1 // CHECK1-NEXT: [[TMP7:%.*]] = bitcast i8** [[TMP6]] to i32** -// CHECK1-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 2 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast i8** [[TMP9]] to %"class.std::complex.0"** -// CHECK1-NEXT: [[TMP11:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[TMP10]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: call void @__omp_outlined__3(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex.0"* [[TMP11]]) #[[ATTR5]] +// CHECK1-NEXT: [[TMP11:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[TMP10]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: call void @__omp_outlined__3(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex.0"* [[TMP11]]) #[[ATTR6]] // CHECK1-NEXT: ret void // // // CHECK1-LABEL: define {{[^@]+}}@_ZNSt7complexIfEC2ERKfS2_ -// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 // CHECK1-NEXT: [[__RE_ADDR:%.*]] = alloca float*, align 8 // CHECK1-NEXT: [[__IM_ADDR:%.*]] = alloca float*, align 8 -// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP1:%.*]] = load float, float* [[TMP0]], align 4, !tbaa [[TBAA14]] -// CHECK1-NEXT: store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA16]] +// CHECK1-NEXT: [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP1:%.*]] = load float, float* [[TMP0]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA26]] // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP2:%.*]] = load float*, float** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP3:%.*]] = load float, float* [[TMP2]], align 4, !tbaa [[TBAA14]] -// CHECK1-NEXT: store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA18]] +// CHECK1-NEXT: [[TMP2:%.*]] = load float*, float** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP3:%.*]] = load float, float* [[TMP2]], align 4, !tbaa [[TBAA19]] +// CHECK1-NEXT: store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK1-NEXT: ret void // // // CHECK1-LABEL: define {{[^@]+}}@_ZNKSt7complexIfE4realEv -// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 -// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA16]] +// CHECK1-NEXT: [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA26]] // CHECK1-NEXT: ret float [[TMP0]] // // // CHECK1-LABEL: define {{[^@]+}}@_ZNKSt7complexIfE4imagEv -// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 -// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA18]] +// CHECK1-NEXT: [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK1-NEXT: ret float [[TMP0]] // // // CHECK1-LABEL: define {{[^@]+}}@_ZNSt7complexIdEC2ERKdS2_ -// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 // CHECK1-NEXT: [[__RE_ADDR:%.*]] = alloca double*, align 8 // CHECK1-NEXT: [[__IM_ADDR:%.*]] = alloca double*, align 8 -// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !tbaa [[TBAA22]] -// CHECK1-NEXT: store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA24]] +// CHECK1-NEXT: [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !tbaa [[TBAA37]] +// CHECK1-NEXT: store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA44]] // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP2:%.*]] = load double*, double** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK1-NEXT: [[TMP3:%.*]] = load double, double* [[TMP2]], align 8, !tbaa [[TBAA22]] -// CHECK1-NEXT: store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]] +// CHECK1-NEXT: [[TMP2:%.*]] = load double*, double** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK1-NEXT: [[TMP3:%.*]] = load double, double* [[TMP2]], align 8, !tbaa [[TBAA37]] +// CHECK1-NEXT: store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA46]] // CHECK1-NEXT: ret void // // // CHECK1-LABEL: define {{[^@]+}}@_ZNKSt7complexIdE4realEv -// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 -// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24]] +// CHECK1-NEXT: [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA44]] // CHECK1-NEXT: ret double [[TMP0]] // // // CHECK1-LABEL: define {{[^@]+}}@_ZNKSt7complexIdE4imagEv -// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK1-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 -// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK1-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK1-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK1-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26]] +// CHECK1-NEXT: [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA46]] // CHECK1-NEXT: ret double [[TMP0]] // // @@ -1276,7 +1284,7 @@ // CHECK2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK2-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK2-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA8:![0-9]+]] -// CHECK2-NEXT: call void @__omp_outlined__(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR5:[0-9]+]] +// CHECK2-NEXT: call void @__omp_outlined__(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR6:[0-9]+]] // CHECK2-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true) // CHECK2-NEXT: ret void // CHECK2: worker.exit: @@ -1298,112 +1306,114 @@ // CHECK2-NEXT: [[REF_TMP:%.*]] = alloca float, align 4 // CHECK2-NEXT: [[REF_TMP2:%.*]] = alloca float, align 4 // CHECK2-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [3 x i8*], align 8 -// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12:![0-9]+]] -// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META17:![0-9]+]]) +// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[ISTART:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK2-NEXT: [[ISTART_ON_STACK:%.*]] = bitcast i8* [[ISTART]] to i32* // CHECK2-NEXT: [[IEND:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK2-NEXT: [[IEND_ON_STACK:%.*]] = bitcast i8* [[IEND]] to i32* // CHECK2-NEXT: [[PARTIAL_SUM:%.*]] = call i8* @__kmpc_alloc_shared(i64 8) // CHECK2-NEXT: [[PARTIAL_SUM_ON_STACK:%.*]] = bitcast i8* [[PARTIAL_SUM]] to %"class.std::complex"* -// CHECK2-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP1]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR6]] // CHECK2-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR6]] // CHECK2-NEXT: store i32 99, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] // CHECK2-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] // CHECK2-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP5:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP6:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP7]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) -// CHECK2-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 99 +// CHECK2-NEXT: [[TMP7:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP7]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP9]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 99 // CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK2: cond.true: // CHECK2-NEXT: br label [[COND_END:%.*]] // CHECK2: cond.false: -// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[COND_END]] // CHECK2: cond.end: -// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP9]], [[COND_FALSE]] ] +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ] // CHECK2-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP10]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP12]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP11]], [[TMP12]] +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] // CHECK2-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK2: omp.inner.for.cond.cleanup: // CHECK2-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP13]], 1 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP15]], 1 // CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] // CHECK2-NEXT: store i32 [[ADD]], i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP14:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP14]]) #[[ATTR5]] -// CHECK2-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA14:![0-9]+]] -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast float* [[REF_TMP2]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP15]]) #[[ATTR5]] -// CHECK2-NEXT: store float 0.000000e+00, float* [[REF_TMP2]], align 4, !tbaa [[TBAA14]] -// CHECK2-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM_ON_STACK]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR11:[0-9]+]] -// CHECK2-NEXT: [[TMP16:%.*]] = bitcast float* [[REF_TMP2]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP17:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP18]], 4 +// CHECK2-NEXT: [[TMP16:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR6]] +// CHECK2-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA19:![0-9]+]] +// CHECK2-NEXT: [[TMP17:%.*]] = bitcast float* [[REF_TMP2]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR6]] +// CHECK2-NEXT: store float 0.000000e+00, float* [[REF_TMP2]], align 4, !tbaa [[TBAA19]] +// CHECK2-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM_ON_STACK]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR13:[0-9]+]] +// CHECK2-NEXT: [[TMP18:%.*]] = bitcast float* [[REF_TMP2]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP18]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP19:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP20]], 4 // CHECK2-NEXT: store i32 [[MUL3]], i32* [[ISTART_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP19]], 1 +// CHECK2-NEXT: [[TMP21:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK2-NEXT: [[MUL5:%.*]] = mul nsw i32 [[ADD4]], 4 // CHECK2-NEXT: store i32 [[MUL5]], i32* [[IEND_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 -// CHECK2-NEXT: [[TMP23:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* -// CHECK2-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 -// CHECK2-NEXT: [[TMP25:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM_ON_STACK]] to i8* -// CHECK2-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP26:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -// CHECK2-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP7]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex"*)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** [[TMP26]], i64 3) +// CHECK2-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 +// CHECK2-NEXT: [[TMP25:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 +// CHECK2-NEXT: [[TMP27:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM_ON_STACK]] to i8* +// CHECK2-NEXT: store i8* [[TMP27]], i8** [[TMP26]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP28:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +// CHECK2-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP9]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex"*)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** [[TMP28]], i64 3) // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP27]], 1 +// CHECK2-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP29]], 1 // CHECK2-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]]) -// CHECK2-NEXT: [[TMP28:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP29]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP30:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR5]] +// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP9]]) +// CHECK2-NEXT: [[TMP30:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP34:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP34]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP35:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP35]]) #[[ATTR6]] // CHECK2-NEXT: call void @__kmpc_free_shared(i8* [[PARTIAL_SUM]], i64 8) // CHECK2-NEXT: call void @__kmpc_free_shared(i8* [[IEND]], i64 4) // CHECK2-NEXT: call void @__kmpc_free_shared(i8* [[ISTART]], i64 4) @@ -1411,18 +1421,18 @@ // // // CHECK2-LABEL: define {{[^@]+}}@_ZNSt7complexIfEC1ERKfS2_ -// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR3:[0-9]+]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR4:[0-9]+]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 // CHECK2-NEXT: [[__RE_ADDR:%.*]] = alloca float*, align 8 // CHECK2-NEXT: [[__IM_ADDR:%.*]] = alloca float*, align 8 -// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK2-NEXT: [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8 // CHECK2-NEXT: [[TMP1:%.*]] = load float*, float** [[__IM_ADDR]], align 8 -// CHECK2-NEXT: call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR11]] +// CHECK2-NEXT: call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR13]] // CHECK2-NEXT: ret void // // @@ -1452,224 +1462,226 @@ // CHECK2-NEXT: [[REF_TMP15:%.*]] = alloca float, align 4 // CHECK2-NEXT: [[REF_TMP16:%.*]] = alloca float, align 4 // CHECK2-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 -// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store %"class.std::complex"* [[PARTIAL_SUM]], %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP0]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP5]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[SUB:%.*]] = sub i32 [[TMP9]], [[TMP10]] +// CHECK2-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META21:![0-9]+]]) +// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META24:![0-9]+]]) +// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store %"class.std::complex"* [[PARTIAL_SUM]], %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP3:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP4:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP2]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP9]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP10:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP10]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[SUB:%.*]] = sub i32 [[TMP11]], [[TMP12]] // CHECK2-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 // CHECK2-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 1 // CHECK2-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 1 // CHECK2-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 // CHECK2-NEXT: store i32 [[SUB4]], i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP11:%.*]] = bitcast i32* [[I]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP11]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP12]], i32* [[I]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: [[TMP13:%.*]] = bitcast i32* [[I]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR5]] +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR6]] // CHECK2-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP14]], [[TMP15]] +// CHECK2-NEXT: store i32 [[TMP14]], i32* [[I]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP15:%.*]] = bitcast i32* [[I]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP15]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP16]], [[TMP17]] // CHECK2-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] // CHECK2: omp.precond.then: -// CHECK2-NEXT: [[TMP16:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP18:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP18]]) #[[ATTR6]] // CHECK2-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP17:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP18]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP21]]) #[[ATTR6]] // CHECK2-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP20:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP20]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP22:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP22]]) #[[ATTR6]] // CHECK2-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP22:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP22]]) #[[ATTR5]] -// CHECK2-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA14]] -// CHECK2-NEXT: [[TMP23:%.*]] = bitcast float* [[REF_TMP6]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP23]]) #[[ATTR5]] -// CHECK2-NEXT: store float 0.000000e+00, float* [[REF_TMP6]], align 4, !tbaa [[TBAA14]] -// CHECK2-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR11]] -// CHECK2-NEXT: [[TMP24:%.*]] = bitcast float* [[REF_TMP6]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP24]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP25:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP26:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP26]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP28]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP23]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP24:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP24]]) #[[ATTR6]] +// CHECK2-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA19]] +// CHECK2-NEXT: [[TMP25:%.*]] = bitcast float* [[REF_TMP6]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP25]]) #[[ATTR6]] +// CHECK2-NEXT: store float 0.000000e+00, float* [[REF_TMP6]], align 4, !tbaa [[TBAA19]] +// CHECK2-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR13]] +// CHECK2-NEXT: [[TMP26:%.*]] = bitcast float* [[REF_TMP6]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP26]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP27:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP27]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP28:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP30]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK2-NEXT: br label [[OMP_DISPATCH_COND:%.*]] // CHECK2: omp.dispatch.cond: -// CHECK2-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP29]], [[TMP30]] +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP31]], [[TMP32]] // CHECK2-NEXT: br i1 [[CMP8]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK2: cond.true: -// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[COND_END:%.*]] // CHECK2: cond.false: -// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[COND_END]] // CHECK2: cond.end: -// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ [[TMP31]], [[COND_TRUE]] ], [ [[TMP32]], [[COND_FALSE]] ] +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ [[TMP33]], [[COND_TRUE]] ], [ [[TMP34]], [[COND_FALSE]] ] // CHECK2-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP33]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD9:%.*]] = add i32 [[TMP35]], 1 -// CHECK2-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP34]], [[ADD9]] +// CHECK2-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP35]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD9:%.*]] = add i32 [[TMP37]], 1 +// CHECK2-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP36]], [[ADD9]] // CHECK2-NEXT: br i1 [[CMP10]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_CLEANUP:%.*]] // CHECK2: omp.dispatch.cleanup: // CHECK2-NEXT: br label [[OMP_DISPATCH_END:%.*]] // CHECK2: omp.dispatch.body: // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD11:%.*]] = add i32 [[TMP37]], 1 -// CHECK2-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP36]], [[ADD11]] +// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD11:%.*]] = add i32 [[TMP39]], 1 +// CHECK2-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP38]], [[ADD11]] // CHECK2-NEXT: br i1 [[CMP12]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK2: omp.inner.for.cond.cleanup: // CHECK2-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[MUL:%.*]] = mul i32 [[TMP39]], 1 -// CHECK2-NEXT: [[ADD13:%.*]] = add i32 [[TMP38]], [[MUL]] +// CHECK2-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[MUL:%.*]] = mul i32 [[TMP41]], 1 +// CHECK2-NEXT: [[ADD13:%.*]] = add i32 [[TMP40]], [[MUL]] // CHECK2-NEXT: store i32 [[ADD13]], i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP40:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP40]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = bitcast float* [[REF_TMP15]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP41]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP42:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP42]] to float -// CHECK2-NEXT: store float [[CONV]], float* [[REF_TMP15]], align 4, !tbaa [[TBAA14]] -// CHECK2-NEXT: [[TMP43:%.*]] = bitcast float* [[REF_TMP16]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP43]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP42:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP42]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP43:%.*]] = bitcast float* [[REF_TMP15]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP43]]) #[[ATTR6]] // CHECK2-NEXT: [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP44]] to float -// CHECK2-NEXT: store float [[CONV17]], float* [[REF_TMP16]], align 4, !tbaa [[TBAA14]] -// CHECK2-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR11]] -// CHECK2-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR11]] +// CHECK2-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP44]] to float +// CHECK2-NEXT: store float [[CONV]], float* [[REF_TMP15]], align 4, !tbaa [[TBAA19]] // CHECK2-NEXT: [[TMP45:%.*]] = bitcast float* [[REF_TMP16]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP45]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP46:%.*]] = bitcast float* [[REF_TMP15]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP46]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP47:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP47]]) #[[ATTR5]] +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP45]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP46]] to float +// CHECK2-NEXT: store float [[CONV17]], float* [[REF_TMP16]], align 4, !tbaa [[TBAA19]] +// CHECK2-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR13]] +// CHECK2-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR13]] +// CHECK2-NEXT: [[TMP47:%.*]] = bitcast float* [[REF_TMP16]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP47]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP48:%.*]] = bitcast float* [[REF_TMP15]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP48]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP49:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP49]]) #[[ATTR6]] // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD18:%.*]] = add i32 [[TMP48]], 1 +// CHECK2-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD18:%.*]] = add i32 [[TMP50]], 1 // CHECK2-NEXT: store i32 [[ADD18]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK2: omp.dispatch.inc: -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD19:%.*]] = add i32 [[TMP49]], [[TMP50]] -// CHECK2-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD20:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK2-NEXT: [[ADD19:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK2-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD20:%.*]] = add i32 [[TMP53]], [[TMP54]] // CHECK2-NEXT: store i32 [[ADD20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK2: omp.dispatch.end: -// CHECK2-NEXT: [[TMP53:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP54]]) // CHECK2-NEXT: [[TMP55:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP55]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP57:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP58:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* -// CHECK2-NEXT: store i8* [[TMP58]], i8** [[TMP57]], align 8 -// CHECK2-NEXT: [[TMP59:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* -// CHECK2-NEXT: [[TMP60:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP56]], i32 1, i64 8, i8* [[TMP59]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func) -// CHECK2-NEXT: [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1 -// CHECK2-NEXT: br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] +// CHECK2-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP56]]) +// CHECK2-NEXT: [[TMP57:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[TMP57]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP59:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP60:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* +// CHECK2-NEXT: store i8* [[TMP60]], i8** [[TMP59]], align 8 +// CHECK2-NEXT: [[TMP61:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* +// CHECK2-NEXT: [[TMP62:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP58]], i32 1, i64 8, i8* [[TMP61]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func) +// CHECK2-NEXT: [[TMP63:%.*]] = icmp eq i32 [[TMP62]], 1 +// CHECK2-NEXT: br i1 [[TMP63]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] // CHECK2: .omp.reduction.then: -// CHECK2-NEXT: [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR11]] -// CHECK2-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]]) +// CHECK2-NEXT: [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP4]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR13]] +// CHECK2-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP58]]) // CHECK2-NEXT: br label [[DOTOMP_REDUCTION_DONE]] // CHECK2: .omp.reduction.done: -// CHECK2-NEXT: [[TMP62:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP63:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP63]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP64:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP65:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP65]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR6]] // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: -// CHECK2-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP72:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP73:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR6]] // CHECK2-NEXT: ret void // // // CHECK2-LABEL: define {{[^@]+}}@_ZNSt7complexIfEpLIfEERS0_RKS_IT_E -// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[__C:%.*]]) #[[ATTR4:[0-9]+]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[__C:%.*]]) #[[ATTR5:[0-9]+]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 // CHECK2-NEXT: [[__C_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 -// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store %"class.std::complex"* [[__C]], %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store %"class.std::complex"* [[__C]], %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 -// CHECK2-NEXT: [[TMP0:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP0]]) #[[ATTR11]] +// CHECK2-NEXT: [[TMP0:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP0]]) #[[ATTR13]] // CHECK2-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA16:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA26:![0-9]+]] // CHECK2-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[CALL]] -// CHECK2-NEXT: store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA16]] -// CHECK2-NEXT: [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]]) #[[ATTR11]] +// CHECK2-NEXT: store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA26]] +// CHECK2-NEXT: [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]]) #[[ATTR13]] // CHECK2-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA18:![0-9]+]] +// CHECK2-NEXT: [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA28:![0-9]+]] // CHECK2-NEXT: [[ADD3:%.*]] = fadd float [[TMP3]], [[CALL2]] -// CHECK2-NEXT: store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA18]] +// CHECK2-NEXT: store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK2-NEXT: ret %"class.std::complex"* [[THIS1]] // // // CHECK2-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func -// CHECK2-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR6:[0-9]+]] { +// CHECK2-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR7:[0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK2-NEXT: [[DOTADDR1:%.*]] = alloca i16, align 2 @@ -1677,15 +1689,15 @@ // CHECK2-NEXT: [[DOTADDR3:%.*]] = alloca i16, align 2 // CHECK2-NEXT: [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST:%.*]] = alloca [1 x i8*], align 8 // CHECK2-NEXT: [[DOTOMP_REDUCTION_ELEMENT:%.*]] = alloca %"class.std::complex", align 4 -// CHECK2-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19:![0-9]+]] -// CHECK2-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK2-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] -// CHECK2-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29:![0-9]+]] +// CHECK2-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK2-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] +// CHECK2-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]* -// CHECK2-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19]] -// CHECK2-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK2-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] +// CHECK2-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29]] +// CHECK2-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0 // CHECK2-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8 // CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]], i64 0, i64 0 @@ -1702,7 +1714,7 @@ // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr i64, i64* [[TMP15]], i64 1 // CHECK2-NEXT: [[TMP21:%.*]] = getelementptr i64, i64* [[TMP16]], i64 1 // CHECK2-NEXT: [[TMP22:%.*]] = bitcast %"class.std::complex"* [[DOTOMP_REDUCTION_ELEMENT]] to i8* -// CHECK2-NEXT: store i8* [[TMP22]], i8** [[TMP11]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store i8* [[TMP22]], i8** [[TMP11]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP23:%.*]] = icmp eq i16 [[TMP8]], 0 // CHECK2-NEXT: [[TMP24:%.*]] = icmp eq i16 [[TMP8]], 1 // CHECK2-NEXT: [[TMP25:%.*]] = icmp ult i16 [[TMP6]], [[TMP7]] @@ -1719,7 +1731,7 @@ // CHECK2: then: // CHECK2-NEXT: [[TMP35:%.*]] = bitcast [1 x i8*]* [[TMP5]] to i8* // CHECK2-NEXT: [[TMP36:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]] to i8* -// CHECK2-NEXT: call void @"_omp$reduction$reduction_func"(i8* [[TMP35]], i8* [[TMP36]]) #[[ATTR5]] +// CHECK2-NEXT: call void @"_omp$reduction$reduction_func"(i8* [[TMP35]], i8* [[TMP36]]) #[[ATTR6]] // CHECK2-NEXT: br label [[IFCONT:%.*]] // CHECK2: else: // CHECK2-NEXT: br label [[IFCONT]] @@ -1737,7 +1749,7 @@ // CHECK2-NEXT: [[TMP45:%.*]] = bitcast i8* [[TMP43]] to %"class.std::complex"* // CHECK2-NEXT: [[TMP46:%.*]] = bitcast %"class.std::complex"* [[TMP45]] to i8* // CHECK2-NEXT: [[TMP47:%.*]] = bitcast %"class.std::complex"* [[TMP44]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !21 +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !31 // CHECK2-NEXT: br label [[IFCONT6:%.*]] // CHECK2: else5: // CHECK2-NEXT: br label [[IFCONT6]] @@ -1746,13 +1758,13 @@ // // // CHECK2-LABEL: define {{[^@]+}}@_omp_reduction_inter_warp_copy_func -// CHECK2-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK2-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK2-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTCNT_ADDR:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) -// CHECK2-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: [[NVPTX_TID:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() // CHECK2-NEXT: [[NVPTX_TID2:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() @@ -1773,7 +1785,7 @@ // CHECK2-NEXT: br i1 [[WARP_MASTER]], label [[THEN:%.*]], label [[ELSE:%.*]] // CHECK2: then: // CHECK2-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP9:%.*]] = bitcast i8* [[TMP8]] to i32* // CHECK2-NEXT: [[TMP10:%.*]] = getelementptr i32, i32* [[TMP9]], i32 [[TMP5]] // CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] @@ -1790,7 +1802,7 @@ // CHECK2: then2: // CHECK2-NEXT: [[TMP14:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_TID]] // CHECK2-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to i32* // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr i32, i32* [[TMP17]], i32 [[TMP5]] // CHECK2-NEXT: [[TMP19:%.*]] = load volatile i32, i32 addrspace(3)* [[TMP14]], align 4, !tbaa [[TBAA8]] @@ -1807,27 +1819,27 @@ // // // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper -// CHECK2-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK2-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 // CHECK2-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8 -// CHECK2-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA19]] +// CHECK2-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA29]] // CHECK2-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK2-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) // CHECK2-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8 // CHECK2-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0 // CHECK2-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32** -// CHECK2-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 1 // CHECK2-NEXT: [[TMP7:%.*]] = bitcast i8** [[TMP6]] to i32** -// CHECK2-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 2 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast i8** [[TMP9]] to %"class.std::complex"** -// CHECK2-NEXT: [[TMP11:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[TMP10]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex"* [[TMP11]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP11:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[TMP10]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex"* [[TMP11]]) #[[ATTR6]] // CHECK2-NEXT: ret void // // @@ -1843,7 +1855,7 @@ // CHECK2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK2-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK2-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: call void @__omp_outlined__2(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR5]] +// CHECK2-NEXT: call void @__omp_outlined__2(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR6]] // CHECK2-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true) // CHECK2-NEXT: ret void // CHECK2: worker.exit: @@ -1865,112 +1877,114 @@ // CHECK2-NEXT: [[REF_TMP:%.*]] = alloca double, align 8 // CHECK2-NEXT: [[REF_TMP2:%.*]] = alloca double, align 8 // CHECK2-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [3 x i8*], align 8 -// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META32:![0-9]+]]) +// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META35:![0-9]+]]) +// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[ISTART:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK2-NEXT: [[ISTART_ON_STACK:%.*]] = bitcast i8* [[ISTART]] to i32* // CHECK2-NEXT: [[IEND:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK2-NEXT: [[IEND_ON_STACK:%.*]] = bitcast i8* [[IEND]] to i32* // CHECK2-NEXT: [[PARTIAL_SUM:%.*]] = call i8* @__kmpc_alloc_shared(i64 16) // CHECK2-NEXT: [[PARTIAL_SUM_ON_STACK:%.*]] = bitcast i8* [[PARTIAL_SUM]] to %"class.std::complex.0"* -// CHECK2-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP1]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR6]] // CHECK2-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR6]] // CHECK2-NEXT: store i32 99, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] // CHECK2-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] // CHECK2-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP5:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP6:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) -// CHECK2-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 99 +// CHECK2-NEXT: [[TMP7:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP7]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP9]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 99 // CHECK2-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK2: cond.true: // CHECK2-NEXT: br label [[COND_END:%.*]] // CHECK2: cond.false: -// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[COND_END]] // CHECK2: cond.end: -// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP9]], [[COND_FALSE]] ] +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ] // CHECK2-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP10]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP12]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP11]], [[TMP12]] +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] // CHECK2-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK2: omp.inner.for.cond.cleanup: // CHECK2-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP13]], 1 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP15]], 1 // CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] // CHECK2-NEXT: store i32 [[ADD]], i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP14:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP14]]) #[[ATTR5]] -// CHECK2-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA22:![0-9]+]] -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast double* [[REF_TMP2]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP15]]) #[[ATTR5]] -// CHECK2-NEXT: store double 0.000000e+00, double* [[REF_TMP2]], align 8, !tbaa [[TBAA22]] -// CHECK2-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM_ON_STACK]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR11]] -// CHECK2-NEXT: [[TMP16:%.*]] = bitcast double* [[REF_TMP2]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP16]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP17:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP17]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP18]], 4 +// CHECK2-NEXT: [[TMP16:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP16]]) #[[ATTR6]] +// CHECK2-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA37:![0-9]+]] +// CHECK2-NEXT: [[TMP17:%.*]] = bitcast double* [[REF_TMP2]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP17]]) #[[ATTR6]] +// CHECK2-NEXT: store double 0.000000e+00, double* [[REF_TMP2]], align 8, !tbaa [[TBAA37]] +// CHECK2-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM_ON_STACK]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR13]] +// CHECK2-NEXT: [[TMP18:%.*]] = bitcast double* [[REF_TMP2]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP18]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP19:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP19]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP20]], 4 // CHECK2-NEXT: store i32 [[MUL3]], i32* [[ISTART_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP19]], 1 +// CHECK2-NEXT: [[TMP21:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK2-NEXT: [[MUL5:%.*]] = mul nsw i32 [[ADD4]], 4 // CHECK2-NEXT: store i32 [[MUL5]], i32* [[IEND_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 -// CHECK2-NEXT: [[TMP23:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* -// CHECK2-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 -// CHECK2-NEXT: [[TMP25:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM_ON_STACK]] to i8* -// CHECK2-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP26:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -// CHECK2-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP7]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex.0"*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP26]], i64 3) +// CHECK2-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 +// CHECK2-NEXT: [[TMP25:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 +// CHECK2-NEXT: [[TMP27:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM_ON_STACK]] to i8* +// CHECK2-NEXT: store i8* [[TMP27]], i8** [[TMP26]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP28:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +// CHECK2-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP9]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex.0"*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP28]], i64 3) // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP27]], 1 +// CHECK2-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP29]], 1 // CHECK2-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: -// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]]) -// CHECK2-NEXT: [[TMP28:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP29]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP30:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR5]] +// CHECK2-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP9]]) +// CHECK2-NEXT: [[TMP30:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP34:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP34]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP35:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP35]]) #[[ATTR6]] // CHECK2-NEXT: call void @__kmpc_free_shared(i8* [[PARTIAL_SUM]], i64 16) // CHECK2-NEXT: call void @__kmpc_free_shared(i8* [[IEND]], i64 4) // CHECK2-NEXT: call void @__kmpc_free_shared(i8* [[ISTART]], i64 4) @@ -1978,18 +1992,18 @@ // // // CHECK2-LABEL: define {{[^@]+}}@_ZNSt7complexIdEC1ERKdS2_ -// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 // CHECK2-NEXT: [[__RE_ADDR:%.*]] = alloca double*, align 8 // CHECK2-NEXT: [[__IM_ADDR:%.*]] = alloca double*, align 8 -// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK2-NEXT: [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8 // CHECK2-NEXT: [[TMP1:%.*]] = load double*, double** [[__IM_ADDR]], align 8 -// CHECK2-NEXT: call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR11]] +// CHECK2-NEXT: call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR13]] // CHECK2-NEXT: ret void // // @@ -2019,224 +2033,226 @@ // CHECK2-NEXT: [[REF_TMP15:%.*]] = alloca double, align 8 // CHECK2-NEXT: [[REF_TMP16:%.*]] = alloca double, align 8 // CHECK2-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 -// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store %"class.std::complex.0"* [[PARTIAL_SUM]], %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP2:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP0]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP5]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[SUB:%.*]] = sub i32 [[TMP9]], [[TMP10]] +// CHECK2-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META39:![0-9]+]]) +// CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META42:![0-9]+]]) +// CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store %"class.std::complex.0"* [[PARTIAL_SUM]], %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP3:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP4:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP2]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP9]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP10:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP10]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[SUB:%.*]] = sub i32 [[TMP11]], [[TMP12]] // CHECK2-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 // CHECK2-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 1 // CHECK2-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 1 // CHECK2-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 // CHECK2-NEXT: store i32 [[SUB4]], i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP11:%.*]] = bitcast i32* [[I]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP11]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP12]], i32* [[I]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: [[TMP13:%.*]] = bitcast i32* [[I]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR5]] +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR6]] // CHECK2-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP14]], [[TMP15]] +// CHECK2-NEXT: store i32 [[TMP14]], i32* [[I]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP15:%.*]] = bitcast i32* [[I]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP15]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP16]], [[TMP17]] // CHECK2-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] // CHECK2: omp.precond.then: -// CHECK2-NEXT: [[TMP16:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP18:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP18]]) #[[ATTR6]] // CHECK2-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP17:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP18]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP21]]) #[[ATTR6]] // CHECK2-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP20:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP20]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP22:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP22]]) #[[ATTR6]] // CHECK2-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP22:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP22]]) #[[ATTR5]] -// CHECK2-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA22]] -// CHECK2-NEXT: [[TMP23:%.*]] = bitcast double* [[REF_TMP6]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP23]]) #[[ATTR5]] -// CHECK2-NEXT: store double 0.000000e+00, double* [[REF_TMP6]], align 8, !tbaa [[TBAA22]] -// CHECK2-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR11]] -// CHECK2-NEXT: [[TMP24:%.*]] = bitcast double* [[REF_TMP6]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP24]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP25:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP26:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP26]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3]], i32 [[TMP28]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP23]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP24:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP24]]) #[[ATTR6]] +// CHECK2-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA37]] +// CHECK2-NEXT: [[TMP25:%.*]] = bitcast double* [[REF_TMP6]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP25]]) #[[ATTR6]] +// CHECK2-NEXT: store double 0.000000e+00, double* [[REF_TMP6]], align 8, !tbaa [[TBAA37]] +// CHECK2-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR13]] +// CHECK2-NEXT: [[TMP26:%.*]] = bitcast double* [[REF_TMP6]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP26]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP27:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP27]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP28:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK2-NEXT: br label [[OMP_DISPATCH_COND:%.*]] // CHECK2: omp.dispatch.cond: -// CHECK2-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP29]], [[TMP30]] +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP31]], [[TMP32]] // CHECK2-NEXT: br i1 [[CMP8]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK2: cond.true: -// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[COND_END:%.*]] // CHECK2: cond.false: -// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[COND_END]] // CHECK2: cond.end: -// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ [[TMP31]], [[COND_TRUE]] ], [ [[TMP32]], [[COND_FALSE]] ] +// CHECK2-NEXT: [[COND:%.*]] = phi i32 [ [[TMP33]], [[COND_TRUE]] ], [ [[TMP34]], [[COND_FALSE]] ] // CHECK2-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: store i32 [[TMP33]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD9:%.*]] = add i32 [[TMP35]], 1 -// CHECK2-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP34]], [[ADD9]] +// CHECK2-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: store i32 [[TMP35]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD9:%.*]] = add i32 [[TMP37]], 1 +// CHECK2-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP36]], [[ADD9]] // CHECK2-NEXT: br i1 [[CMP10]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_CLEANUP:%.*]] // CHECK2: omp.dispatch.cleanup: // CHECK2-NEXT: br label [[OMP_DISPATCH_END:%.*]] // CHECK2: omp.dispatch.body: // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD11:%.*]] = add i32 [[TMP37]], 1 -// CHECK2-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP36]], [[ADD11]] +// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD11:%.*]] = add i32 [[TMP39]], 1 +// CHECK2-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP38]], [[ADD11]] // CHECK2-NEXT: br i1 [[CMP12]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK2: omp.inner.for.cond.cleanup: // CHECK2-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[MUL:%.*]] = mul i32 [[TMP39]], 1 -// CHECK2-NEXT: [[ADD13:%.*]] = add i32 [[TMP38]], [[MUL]] +// CHECK2-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[MUL:%.*]] = mul i32 [[TMP41]], 1 +// CHECK2-NEXT: [[ADD13:%.*]] = add i32 [[TMP40]], [[MUL]] // CHECK2-NEXT: store i32 [[ADD13]], i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP40:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP40]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = bitcast double* [[REF_TMP15]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP41]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP42:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP42]] to double -// CHECK2-NEXT: store double [[CONV]], double* [[REF_TMP15]], align 8, !tbaa [[TBAA22]] -// CHECK2-NEXT: [[TMP43:%.*]] = bitcast double* [[REF_TMP16]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP43]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP42:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP42]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP43:%.*]] = bitcast double* [[REF_TMP15]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP43]]) #[[ATTR6]] // CHECK2-NEXT: [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP44]] to double -// CHECK2-NEXT: store double [[CONV17]], double* [[REF_TMP16]], align 8, !tbaa [[TBAA22]] -// CHECK2-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR11]] -// CHECK2-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR11]] +// CHECK2-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP44]] to double +// CHECK2-NEXT: store double [[CONV]], double* [[REF_TMP15]], align 8, !tbaa [[TBAA37]] // CHECK2-NEXT: [[TMP45:%.*]] = bitcast double* [[REF_TMP16]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP45]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP46:%.*]] = bitcast double* [[REF_TMP15]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP46]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP47:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP47]]) #[[ATTR5]] +// CHECK2-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP45]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP46]] to double +// CHECK2-NEXT: store double [[CONV17]], double* [[REF_TMP16]], align 8, !tbaa [[TBAA37]] +// CHECK2-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR13]] +// CHECK2-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR13]] +// CHECK2-NEXT: [[TMP47:%.*]] = bitcast double* [[REF_TMP16]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP47]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP48:%.*]] = bitcast double* [[REF_TMP15]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP48]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP49:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP49]]) #[[ATTR6]] // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD18:%.*]] = add i32 [[TMP48]], 1 +// CHECK2-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD18:%.*]] = add i32 [[TMP50]], 1 // CHECK2-NEXT: store i32 [[ADD18]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK2: omp.dispatch.inc: -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD19:%.*]] = add i32 [[TMP49]], [[TMP50]] -// CHECK2-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[ADD20:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK2-NEXT: [[ADD19:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK2-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[ADD20:%.*]] = add i32 [[TMP53]], [[TMP54]] // CHECK2-NEXT: store i32 [[ADD20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK2: omp.dispatch.end: -// CHECK2-NEXT: [[TMP53:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP54]]) // CHECK2-NEXT: [[TMP55:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP55]], align 4, !tbaa [[TBAA8]] -// CHECK2-NEXT: [[TMP57:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP58:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* -// CHECK2-NEXT: store i8* [[TMP58]], i8** [[TMP57]], align 8 -// CHECK2-NEXT: [[TMP59:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* -// CHECK2-NEXT: [[TMP60:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP56]], i32 1, i64 8, i8* [[TMP59]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func5, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func6) -// CHECK2-NEXT: [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1 -// CHECK2-NEXT: br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] +// CHECK2-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP56]]) +// CHECK2-NEXT: [[TMP57:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[TMP57]], align 4, !tbaa [[TBAA8]] +// CHECK2-NEXT: [[TMP59:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP60:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* +// CHECK2-NEXT: store i8* [[TMP60]], i8** [[TMP59]], align 8 +// CHECK2-NEXT: [[TMP61:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* +// CHECK2-NEXT: [[TMP62:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP58]], i32 1, i64 8, i8* [[TMP61]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func5, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func6) +// CHECK2-NEXT: [[TMP63:%.*]] = icmp eq i32 [[TMP62]], 1 +// CHECK2-NEXT: br i1 [[TMP63]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] // CHECK2: .omp.reduction.then: -// CHECK2-NEXT: [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP2]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR11]] -// CHECK2-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]]) +// CHECK2-NEXT: [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP4]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR13]] +// CHECK2-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP58]]) // CHECK2-NEXT: br label [[DOTOMP_REDUCTION_DONE]] // CHECK2: .omp.reduction.done: -// CHECK2-NEXT: [[TMP62:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP63:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP63]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP64:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP65:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP65]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR6]] // CHECK2-NEXT: br label [[OMP_PRECOND_END]] // CHECK2: omp.precond.end: -// CHECK2-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP72:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR6]] +// CHECK2-NEXT: [[TMP73:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK2-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR6]] // CHECK2-NEXT: ret void // // // CHECK2-LABEL: define {{[^@]+}}@_ZNSt7complexIdEpLIdEERS0_RKS_IT_E -// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[__C:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[__C:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 // CHECK2-NEXT: [[__C_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 -// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store %"class.std::complex.0"* [[__C]], %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store %"class.std::complex.0"* [[__C]], %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 -// CHECK2-NEXT: [[TMP0:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP0]]) #[[ATTR11]] +// CHECK2-NEXT: [[TMP0:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP0]]) #[[ATTR13]] // CHECK2-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA44:![0-9]+]] // CHECK2-NEXT: [[ADD:%.*]] = fadd double [[TMP1]], [[CALL]] -// CHECK2-NEXT: store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA24]] -// CHECK2-NEXT: [[TMP2:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP2]]) #[[ATTR11]] +// CHECK2-NEXT: store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA44]] +// CHECK2-NEXT: [[TMP2:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP2]]) #[[ATTR13]] // CHECK2-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26:![0-9]+]] +// CHECK2-NEXT: [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA46:![0-9]+]] // CHECK2-NEXT: [[ADD3:%.*]] = fadd double [[TMP3]], [[CALL2]] -// CHECK2-NEXT: store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]] +// CHECK2-NEXT: store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA46]] // CHECK2-NEXT: ret %"class.std::complex.0"* [[THIS1]] // // // CHECK2-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func5 -// CHECK2-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR6]] { +// CHECK2-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR7]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK2-NEXT: [[DOTADDR1:%.*]] = alloca i16, align 2 @@ -2244,15 +2260,15 @@ // CHECK2-NEXT: [[DOTADDR3:%.*]] = alloca i16, align 2 // CHECK2-NEXT: [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST:%.*]] = alloca [1 x i8*], align 8 // CHECK2-NEXT: [[DOTOMP_REDUCTION_ELEMENT:%.*]] = alloca %"class.std::complex.0", align 8 -// CHECK2-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19]] -// CHECK2-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK2-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] -// CHECK2-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29]] +// CHECK2-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK2-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] +// CHECK2-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]* -// CHECK2-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19]] -// CHECK2-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK2-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] +// CHECK2-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29]] +// CHECK2-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0 // CHECK2-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8 // CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]], i64 0, i64 0 @@ -2283,7 +2299,7 @@ // CHECK2-NEXT: br label [[DOTSHUFFLE_PRE_COND]] // CHECK2: .shuffle.exit: // CHECK2-NEXT: [[TMP30:%.*]] = bitcast %"class.std::complex.0"* [[DOTOMP_REDUCTION_ELEMENT]] to i8* -// CHECK2-NEXT: store i8* [[TMP30]], i8** [[TMP11]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store i8* [[TMP30]], i8** [[TMP11]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP31:%.*]] = icmp eq i16 [[TMP8]], 0 // CHECK2-NEXT: [[TMP32:%.*]] = icmp eq i16 [[TMP8]], 1 // CHECK2-NEXT: [[TMP33:%.*]] = icmp ult i16 [[TMP6]], [[TMP7]] @@ -2300,7 +2316,7 @@ // CHECK2: then: // CHECK2-NEXT: [[TMP43:%.*]] = bitcast [1 x i8*]* [[TMP5]] to i8* // CHECK2-NEXT: [[TMP44:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]] to i8* -// CHECK2-NEXT: call void @"_omp$reduction$reduction_func4"(i8* [[TMP43]], i8* [[TMP44]]) #[[ATTR5]] +// CHECK2-NEXT: call void @"_omp$reduction$reduction_func4"(i8* [[TMP43]], i8* [[TMP44]]) #[[ATTR6]] // CHECK2-NEXT: br label [[IFCONT:%.*]] // CHECK2: else: // CHECK2-NEXT: br label [[IFCONT]] @@ -2318,7 +2334,7 @@ // CHECK2-NEXT: [[TMP53:%.*]] = bitcast i8* [[TMP51]] to %"class.std::complex.0"* // CHECK2-NEXT: [[TMP54:%.*]] = bitcast %"class.std::complex.0"* [[TMP53]] to i8* // CHECK2-NEXT: [[TMP55:%.*]] = bitcast %"class.std::complex.0"* [[TMP52]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !27 +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !47 // CHECK2-NEXT: br label [[IFCONT6:%.*]] // CHECK2: else5: // CHECK2-NEXT: br label [[IFCONT6]] @@ -2327,13 +2343,13 @@ // // // CHECK2-LABEL: define {{[^@]+}}@_omp_reduction_inter_warp_copy_func6 -// CHECK2-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK2-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK2-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTCNT_ADDR:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) -// CHECK2-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: [[NVPTX_TID:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() // CHECK2-NEXT: [[NVPTX_TID2:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() @@ -2354,7 +2370,7 @@ // CHECK2-NEXT: br i1 [[WARP_MASTER]], label [[THEN:%.*]], label [[ELSE:%.*]] // CHECK2: then: // CHECK2-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP9:%.*]] = bitcast i8* [[TMP8]] to i32* // CHECK2-NEXT: [[TMP10:%.*]] = getelementptr i32, i32* [[TMP9]], i32 [[TMP5]] // CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] @@ -2371,7 +2387,7 @@ // CHECK2: then2: // CHECK2-NEXT: [[TMP14:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_TID]] // CHECK2-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to i32* // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr i32, i32* [[TMP17]], i32 [[TMP5]] // CHECK2-NEXT: [[TMP19:%.*]] = load volatile i32, i32 addrspace(3)* [[TMP14]], align 4, !tbaa [[TBAA8]] @@ -2388,113 +2404,113 @@ // // // CHECK2-LABEL: define {{[^@]+}}@__omp_outlined__3_wrapper -// CHECK2-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK2-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 // CHECK2-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK2-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8 -// CHECK2-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA19]] +// CHECK2-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA29]] // CHECK2-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK2-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK2-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) // CHECK2-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8 // CHECK2-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0 // CHECK2-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32** -// CHECK2-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 1 // CHECK2-NEXT: [[TMP7:%.*]] = bitcast i8** [[TMP6]] to i32** -// CHECK2-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 2 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast i8** [[TMP9]] to %"class.std::complex.0"** -// CHECK2-NEXT: [[TMP11:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[TMP10]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: call void @__omp_outlined__3(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex.0"* [[TMP11]]) #[[ATTR5]] +// CHECK2-NEXT: [[TMP11:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[TMP10]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: call void @__omp_outlined__3(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex.0"* [[TMP11]]) #[[ATTR6]] // CHECK2-NEXT: ret void // // // CHECK2-LABEL: define {{[^@]+}}@_ZNSt7complexIfEC2ERKfS2_ -// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 // CHECK2-NEXT: [[__RE_ADDR:%.*]] = alloca float*, align 8 // CHECK2-NEXT: [[__IM_ADDR:%.*]] = alloca float*, align 8 -// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK2-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP1:%.*]] = load float, float* [[TMP0]], align 4, !tbaa [[TBAA14]] -// CHECK2-NEXT: store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA16]] +// CHECK2-NEXT: [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP1:%.*]] = load float, float* [[TMP0]], align 4, !tbaa [[TBAA19]] +// CHECK2-NEXT: store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA26]] // CHECK2-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP2:%.*]] = load float*, float** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP3:%.*]] = load float, float* [[TMP2]], align 4, !tbaa [[TBAA14]] -// CHECK2-NEXT: store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA18]] +// CHECK2-NEXT: [[TMP2:%.*]] = load float*, float** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP3:%.*]] = load float, float* [[TMP2]], align 4, !tbaa [[TBAA19]] +// CHECK2-NEXT: store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK2-NEXT: ret void // // // CHECK2-LABEL: define {{[^@]+}}@_ZNKSt7complexIfE4realEv -// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 -// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK2-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA16]] +// CHECK2-NEXT: [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA26]] // CHECK2-NEXT: ret float [[TMP0]] // // // CHECK2-LABEL: define {{[^@]+}}@_ZNKSt7complexIfE4imagEv -// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 -// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK2-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA18]] +// CHECK2-NEXT: [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK2-NEXT: ret float [[TMP0]] // // // CHECK2-LABEL: define {{[^@]+}}@_ZNSt7complexIdEC2ERKdS2_ -// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 // CHECK2-NEXT: [[__RE_ADDR:%.*]] = alloca double*, align 8 // CHECK2-NEXT: [[__IM_ADDR:%.*]] = alloca double*, align 8 -// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK2-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !tbaa [[TBAA22]] -// CHECK2-NEXT: store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA24]] +// CHECK2-NEXT: [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !tbaa [[TBAA37]] +// CHECK2-NEXT: store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA44]] // CHECK2-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP2:%.*]] = load double*, double** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK2-NEXT: [[TMP3:%.*]] = load double, double* [[TMP2]], align 8, !tbaa [[TBAA22]] -// CHECK2-NEXT: store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]] +// CHECK2-NEXT: [[TMP2:%.*]] = load double*, double** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK2-NEXT: [[TMP3:%.*]] = load double, double* [[TMP2]], align 8, !tbaa [[TBAA37]] +// CHECK2-NEXT: store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA46]] // CHECK2-NEXT: ret void // // // CHECK2-LABEL: define {{[^@]+}}@_ZNKSt7complexIdE4realEv -// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 -// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK2-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24]] +// CHECK2-NEXT: [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA44]] // CHECK2-NEXT: ret double [[TMP0]] // // // CHECK2-LABEL: define {{[^@]+}}@_ZNKSt7complexIdE4imagEv -// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK2-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 -// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK2-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK2-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK2-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26]] +// CHECK2-NEXT: [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA46]] // CHECK2-NEXT: ret double [[TMP0]] // // @@ -2510,7 +2526,7 @@ // CHECK3-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK3-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK3-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA8:![0-9]+]] -// CHECK3-NEXT: call void @__omp_outlined__(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR5:[0-9]+]] +// CHECK3-NEXT: call void @__omp_outlined__(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR6:[0-9]+]] // CHECK3-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true) // CHECK3-NEXT: ret void // CHECK3: worker.exit: @@ -2532,112 +2548,114 @@ // CHECK3-NEXT: [[REF_TMP:%.*]] = alloca float, align 4 // CHECK3-NEXT: [[REF_TMP2:%.*]] = alloca float, align 4 // CHECK3-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [3 x i8*], align 8 -// CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12:![0-9]+]] -// CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META12:![0-9]+]]) +// CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15:![0-9]+]] +// CHECK3-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META17:![0-9]+]]) +// CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[ISTART:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK3-NEXT: [[ISTART_ON_STACK:%.*]] = bitcast i8* [[ISTART]] to i32* // CHECK3-NEXT: [[IEND:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK3-NEXT: [[IEND_ON_STACK:%.*]] = bitcast i8* [[IEND]] to i32* // CHECK3-NEXT: [[PARTIAL_SUM:%.*]] = call i8* @__kmpc_alloc_shared(i64 8) // CHECK3-NEXT: [[PARTIAL_SUM_ON_STACK:%.*]] = bitcast i8* [[PARTIAL_SUM]] to %"class.std::complex"* -// CHECK3-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP1]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR6]] // CHECK3-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR6]] // CHECK3-NEXT: store i32 99, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] // CHECK3-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] // CHECK3-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP5:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP6:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP7]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) -// CHECK3-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 99 +// CHECK3-NEXT: [[TMP7:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP7]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2:[0-9]+]], i32 [[TMP9]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 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: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[COND_END]] // CHECK3: cond.end: -// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP9]], [[COND_FALSE]] ] +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ] // CHECK3-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP10]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP12]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] // CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK3: omp.inner.for.cond.cleanup: // CHECK3-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK3: omp.inner.for.body: -// CHECK3-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP13]], 1 +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP15]], 1 // CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] // CHECK3-NEXT: store i32 [[ADD]], i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP14:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP14]]) #[[ATTR5]] -// CHECK3-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA14:![0-9]+]] -// CHECK3-NEXT: [[TMP15:%.*]] = bitcast float* [[REF_TMP2]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP15]]) #[[ATTR5]] -// CHECK3-NEXT: store float 0.000000e+00, float* [[REF_TMP2]], align 4, !tbaa [[TBAA14]] -// CHECK3-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM_ON_STACK]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR11:[0-9]+]] -// CHECK3-NEXT: [[TMP16:%.*]] = bitcast float* [[REF_TMP2]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP17:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP18:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP18]], 4 +// CHECK3-NEXT: [[TMP16:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR6]] +// CHECK3-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA19:![0-9]+]] +// CHECK3-NEXT: [[TMP17:%.*]] = bitcast float* [[REF_TMP2]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR6]] +// CHECK3-NEXT: store float 0.000000e+00, float* [[REF_TMP2]], align 4, !tbaa [[TBAA19]] +// CHECK3-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM_ON_STACK]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP2]]) #[[ATTR13:[0-9]+]] +// CHECK3-NEXT: [[TMP18:%.*]] = bitcast float* [[REF_TMP2]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP18]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP19:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP20]], 4 // CHECK3-NEXT: store i32 [[MUL3]], i32* [[ISTART_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP19:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[TMP21:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK3-NEXT: [[MUL5:%.*]] = mul nsw i32 [[ADD4]], 4 // CHECK3-NEXT: store i32 [[MUL5]], i32* [[IEND_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP21:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* -// CHECK3-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 -// CHECK3-NEXT: [[TMP23:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* -// CHECK3-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 -// CHECK3-NEXT: [[TMP25:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM_ON_STACK]] to i8* -// CHECK3-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP26:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -// CHECK3-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP7]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex"*)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** [[TMP26]], i64 3) +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* +// CHECK3-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 +// CHECK3-NEXT: [[TMP25:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* +// CHECK3-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 +// CHECK3-NEXT: [[TMP27:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM_ON_STACK]] to i8* +// CHECK3-NEXT: store i8* [[TMP27]], i8** [[TMP26]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP28:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +// CHECK3-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP9]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex"*)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** [[TMP28]], i64 3) // 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: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP27]], 1 +// CHECK3-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP29]], 1 // CHECK3-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]]) -// CHECK3-NEXT: [[TMP28:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP29:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP29]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP30:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR5]] +// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP9]]) +// CHECK3-NEXT: [[TMP30:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP34:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP34]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP35:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP35]]) #[[ATTR6]] // CHECK3-NEXT: call void @__kmpc_free_shared(i8* [[PARTIAL_SUM]], i64 8) // CHECK3-NEXT: call void @__kmpc_free_shared(i8* [[IEND]], i64 4) // CHECK3-NEXT: call void @__kmpc_free_shared(i8* [[ISTART]], i64 4) @@ -2645,18 +2663,18 @@ // // // CHECK3-LABEL: define {{[^@]+}}@_ZNSt7complexIfEC1ERKfS2_ -// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR3:[0-9]+]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR4:[0-9]+]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 // CHECK3-NEXT: [[__RE_ADDR:%.*]] = alloca float*, align 8 // CHECK3-NEXT: [[__IM_ADDR:%.*]] = alloca float*, align 8 -// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK3-NEXT: [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8 // CHECK3-NEXT: [[TMP1:%.*]] = load float*, float** [[__IM_ADDR]], align 8 -// CHECK3-NEXT: call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR11]] +// CHECK3-NEXT: call void @_ZNSt7complexIfEC2ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS1]], float* nonnull align 4 dereferenceable(4) [[TMP0]], float* nonnull align 4 dereferenceable(4) [[TMP1]]) #[[ATTR13]] // CHECK3-NEXT: ret void // // @@ -2686,224 +2704,226 @@ // CHECK3-NEXT: [[REF_TMP15:%.*]] = alloca float, align 4 // CHECK3-NEXT: [[REF_TMP16:%.*]] = alloca float, align 4 // CHECK3-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 -// CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store %"class.std::complex"* [[PARTIAL_SUM]], %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP0:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP1:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP0]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP5]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[SUB:%.*]] = sub i32 [[TMP9]], [[TMP10]] +// CHECK3-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META21:![0-9]+]]) +// CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META24:![0-9]+]]) +// CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store %"class.std::complex"* [[PARTIAL_SUM]], %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP2:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP3:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP4:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP2]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP9]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP10:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP10]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[SUB:%.*]] = sub i32 [[TMP11]], [[TMP12]] // CHECK3-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 // CHECK3-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 1 // CHECK3-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 1 // CHECK3-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 // CHECK3-NEXT: store i32 [[SUB4]], i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP11:%.*]] = bitcast i32* [[I]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP11]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP12]], i32* [[I]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: [[TMP13:%.*]] = bitcast i32* [[I]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR5]] +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR6]] // CHECK3-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP14]], [[TMP15]] +// CHECK3-NEXT: store i32 [[TMP14]], i32* [[I]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP15:%.*]] = bitcast i32* [[I]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP15]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP16]], [[TMP17]] // CHECK3-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] // CHECK3: omp.precond.then: -// CHECK3-NEXT: [[TMP16:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP18:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP18]]) #[[ATTR6]] // CHECK3-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP17:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP18]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP21:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP21]]) #[[ATTR6]] // CHECK3-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP20:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP20]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP22:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP22]]) #[[ATTR6]] // CHECK3-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP21:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP21]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP22:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP22]]) #[[ATTR5]] -// CHECK3-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA14]] -// CHECK3-NEXT: [[TMP23:%.*]] = bitcast float* [[REF_TMP6]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP23]]) #[[ATTR5]] -// CHECK3-NEXT: store float 0.000000e+00, float* [[REF_TMP6]], align 4, !tbaa [[TBAA14]] -// CHECK3-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR11]] -// CHECK3-NEXT: [[TMP24:%.*]] = bitcast float* [[REF_TMP6]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP24]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP25:%.*]] = bitcast float* [[REF_TMP]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP25]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP26:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP26]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK3-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP28]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP23]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP24:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP24]]) #[[ATTR6]] +// CHECK3-NEXT: store float 0.000000e+00, float* [[REF_TMP]], align 4, !tbaa [[TBAA19]] +// CHECK3-NEXT: [[TMP25:%.*]] = bitcast float* [[REF_TMP6]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP25]]) #[[ATTR6]] +// CHECK3-NEXT: store float 0.000000e+00, float* [[REF_TMP6]], align 4, !tbaa [[TBAA19]] +// CHECK3-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], float* nonnull align 4 dereferenceable(4) [[REF_TMP]], float* nonnull align 4 dereferenceable(4) [[REF_TMP6]]) #[[ATTR13]] +// CHECK3-NEXT: [[TMP26:%.*]] = bitcast float* [[REF_TMP6]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP26]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP27:%.*]] = bitcast float* [[REF_TMP]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP27]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP28:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP30]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK3-NEXT: br label [[OMP_DISPATCH_COND:%.*]] // CHECK3: omp.dispatch.cond: -// CHECK3-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP29]], [[TMP30]] +// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP31]], [[TMP32]] // CHECK3-NEXT: br i1 [[CMP8]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK3: cond.true: -// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[COND_END:%.*]] // CHECK3: cond.false: -// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[COND_END]] // CHECK3: cond.end: -// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ [[TMP31]], [[COND_TRUE]] ], [ [[TMP32]], [[COND_FALSE]] ] +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ [[TMP33]], [[COND_TRUE]] ], [ [[TMP34]], [[COND_FALSE]] ] // CHECK3-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP33]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD9:%.*]] = add i32 [[TMP35]], 1 -// CHECK3-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP34]], [[ADD9]] +// CHECK3-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP35]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD9:%.*]] = add i32 [[TMP37]], 1 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP36]], [[ADD9]] // CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_CLEANUP:%.*]] // CHECK3: omp.dispatch.cleanup: // CHECK3-NEXT: br label [[OMP_DISPATCH_END:%.*]] // CHECK3: omp.dispatch.body: // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD11:%.*]] = add i32 [[TMP37]], 1 -// CHECK3-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP36]], [[ADD11]] +// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD11:%.*]] = add i32 [[TMP39]], 1 +// CHECK3-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP38]], [[ADD11]] // CHECK3-NEXT: br i1 [[CMP12]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK3: omp.inner.for.cond.cleanup: // CHECK3-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK3: omp.inner.for.body: -// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[MUL:%.*]] = mul i32 [[TMP39]], 1 -// CHECK3-NEXT: [[ADD13:%.*]] = add i32 [[TMP38]], [[MUL]] +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[MUL:%.*]] = mul i32 [[TMP41]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add i32 [[TMP40]], [[MUL]] // CHECK3-NEXT: store i32 [[ADD13]], i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP40:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP40]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP41:%.*]] = bitcast float* [[REF_TMP15]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP41]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP42:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP42]] to float -// CHECK3-NEXT: store float [[CONV]], float* [[REF_TMP15]], align 4, !tbaa [[TBAA14]] -// CHECK3-NEXT: [[TMP43:%.*]] = bitcast float* [[REF_TMP16]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP43]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP42:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP42]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP43:%.*]] = bitcast float* [[REF_TMP15]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP43]]) #[[ATTR6]] // CHECK3-NEXT: [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP44]] to float -// CHECK3-NEXT: store float [[CONV17]], float* [[REF_TMP16]], align 4, !tbaa [[TBAA14]] -// CHECK3-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR11]] -// CHECK3-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR11]] +// CHECK3-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP44]] to float +// CHECK3-NEXT: store float [[CONV]], float* [[REF_TMP15]], align 4, !tbaa [[TBAA19]] // CHECK3-NEXT: [[TMP45:%.*]] = bitcast float* [[REF_TMP16]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP45]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP46:%.*]] = bitcast float* [[REF_TMP15]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP46]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP47:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP47]]) #[[ATTR5]] +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP45]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP46:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP46]] to float +// CHECK3-NEXT: store float [[CONV17]], float* [[REF_TMP16]], align 4, !tbaa [[TBAA19]] +// CHECK3-NEXT: call void @_ZNSt7complexIfEC1ERKfS2_(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]], float* nonnull align 4 dereferenceable(4) [[REF_TMP15]], float* nonnull align 4 dereferenceable(4) [[REF_TMP16]]) #[[ATTR13]] +// CHECK3-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[REF_TMP14]]) #[[ATTR13]] +// CHECK3-NEXT: [[TMP47:%.*]] = bitcast float* [[REF_TMP16]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP47]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP48:%.*]] = bitcast float* [[REF_TMP15]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP48]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP49:%.*]] = bitcast %"class.std::complex"* [[REF_TMP14]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP49]]) #[[ATTR6]] // 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: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD18:%.*]] = add i32 [[TMP48]], 1 +// CHECK3-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD18:%.*]] = add i32 [[TMP50]], 1 // CHECK3-NEXT: store i32 [[ADD18]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK3: omp.dispatch.inc: -// CHECK3-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD19:%.*]] = add i32 [[TMP49]], [[TMP50]] -// CHECK3-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD20:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK3-NEXT: [[ADD19:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK3-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD20:%.*]] = add i32 [[TMP53]], [[TMP54]] // CHECK3-NEXT: store i32 [[ADD20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK3: omp.dispatch.end: -// CHECK3-NEXT: [[TMP53:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK3-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP54]]) // CHECK3-NEXT: [[TMP55:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP55]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP57:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP58:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* -// CHECK3-NEXT: store i8* [[TMP58]], i8** [[TMP57]], align 8 -// CHECK3-NEXT: [[TMP59:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* -// CHECK3-NEXT: [[TMP60:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP56]], i32 1, i64 8, i8* [[TMP59]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func) -// CHECK3-NEXT: [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1 -// CHECK3-NEXT: br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] +// CHECK3-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP56]]) +// CHECK3-NEXT: [[TMP57:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP58:%.*]] = load i32, i32* [[TMP57]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 +// CHECK3-NEXT: [[TMP60:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* +// CHECK3-NEXT: store i8* [[TMP60]], i8** [[TMP59]], align 8 +// CHECK3-NEXT: [[TMP61:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* +// CHECK3-NEXT: [[TMP62:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP58]], i32 1, i64 8, i8* [[TMP61]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func) +// CHECK3-NEXT: [[TMP63:%.*]] = icmp eq i32 [[TMP62]], 1 +// CHECK3-NEXT: br i1 [[TMP63]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] // CHECK3: .omp.reduction.then: -// CHECK3-NEXT: [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR11]] -// CHECK3-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]]) +// CHECK3-NEXT: [[CALL21:%.*]] = call nonnull align 4 dereferenceable(8) %"class.std::complex"* @_ZNSt7complexIfEpLIfEERS0_RKS_IT_E(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP4]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[PARTIAL_SUM5]]) #[[ATTR13]] +// CHECK3-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP58]]) // CHECK3-NEXT: br label [[DOTOMP_REDUCTION_DONE]] // CHECK3: .omp.reduction.done: -// CHECK3-NEXT: [[TMP62:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP63:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP63]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP64:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP65:%.*]] = bitcast %"class.std::complex"* [[PARTIAL_SUM5]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP65]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR6]] // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: -// CHECK3-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP72:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP73:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR6]] // CHECK3-NEXT: ret void // // // CHECK3-LABEL: define {{[^@]+}}@_ZNSt7complexIfEpLIfEERS0_RKS_IT_E -// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[__C:%.*]]) #[[ATTR4:[0-9]+]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], %"class.std::complex"* nonnull align 4 dereferenceable(8) [[__C:%.*]]) #[[ATTR5:[0-9]+]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 // CHECK3-NEXT: [[__C_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 -// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store %"class.std::complex"* [[__C]], %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store %"class.std::complex"* [[__C]], %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 -// CHECK3-NEXT: [[TMP0:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP0]]) #[[ATTR11]] +// CHECK3-NEXT: [[TMP0:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[CALL:%.*]] = call float @_ZNKSt7complexIfE4realEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP0]]) #[[ATTR13]] // CHECK3-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA16:![0-9]+]] +// CHECK3-NEXT: [[TMP1:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA26:![0-9]+]] // CHECK3-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[CALL]] -// CHECK3-NEXT: store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA16]] -// CHECK3-NEXT: [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]]) #[[ATTR11]] +// CHECK3-NEXT: store float [[ADD]], float* [[__RE_]], align 4, !tbaa [[TBAA26]] +// CHECK3-NEXT: [[TMP2:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[CALL2:%.*]] = call float @_ZNKSt7complexIfE4imagEv(%"class.std::complex"* nonnull align 4 dereferenceable(8) [[TMP2]]) #[[ATTR13]] // CHECK3-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA18:![0-9]+]] +// CHECK3-NEXT: [[TMP3:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA28:![0-9]+]] // CHECK3-NEXT: [[ADD3:%.*]] = fadd float [[TMP3]], [[CALL2]] -// CHECK3-NEXT: store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA18]] +// CHECK3-NEXT: store float [[ADD3]], float* [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK3-NEXT: ret %"class.std::complex"* [[THIS1]] // // // CHECK3-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func -// CHECK3-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR6:[0-9]+]] { +// CHECK3-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR7:[0-9]+]] { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca i16, align 2 @@ -2911,15 +2931,15 @@ // CHECK3-NEXT: [[DOTADDR3:%.*]] = alloca i16, align 2 // CHECK3-NEXT: [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST:%.*]] = alloca [1 x i8*], align 8 // CHECK3-NEXT: [[DOTOMP_REDUCTION_ELEMENT:%.*]] = alloca %"class.std::complex", align 4 -// CHECK3-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19:![0-9]+]] -// CHECK3-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK3-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] -// CHECK3-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29:![0-9]+]] +// CHECK3-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK3-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] +// CHECK3-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]* -// CHECK3-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19]] -// CHECK3-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK3-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29]] +// CHECK3-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0 // CHECK3-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8 // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]], i64 0, i64 0 @@ -2936,7 +2956,7 @@ // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr i64, i64* [[TMP15]], i64 1 // CHECK3-NEXT: [[TMP21:%.*]] = getelementptr i64, i64* [[TMP16]], i64 1 // CHECK3-NEXT: [[TMP22:%.*]] = bitcast %"class.std::complex"* [[DOTOMP_REDUCTION_ELEMENT]] to i8* -// CHECK3-NEXT: store i8* [[TMP22]], i8** [[TMP11]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store i8* [[TMP22]], i8** [[TMP11]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP23:%.*]] = icmp eq i16 [[TMP8]], 0 // CHECK3-NEXT: [[TMP24:%.*]] = icmp eq i16 [[TMP8]], 1 // CHECK3-NEXT: [[TMP25:%.*]] = icmp ult i16 [[TMP6]], [[TMP7]] @@ -2953,7 +2973,7 @@ // CHECK3: then: // CHECK3-NEXT: [[TMP35:%.*]] = bitcast [1 x i8*]* [[TMP5]] to i8* // CHECK3-NEXT: [[TMP36:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]] to i8* -// CHECK3-NEXT: call void @"_omp$reduction$reduction_func"(i8* [[TMP35]], i8* [[TMP36]]) #[[ATTR5]] +// CHECK3-NEXT: call void @"_omp$reduction$reduction_func"(i8* [[TMP35]], i8* [[TMP36]]) #[[ATTR6]] // CHECK3-NEXT: br label [[IFCONT:%.*]] // CHECK3: else: // CHECK3-NEXT: br label [[IFCONT]] @@ -2971,7 +2991,7 @@ // CHECK3-NEXT: [[TMP45:%.*]] = bitcast i8* [[TMP43]] to %"class.std::complex"* // CHECK3-NEXT: [[TMP46:%.*]] = bitcast %"class.std::complex"* [[TMP45]] to i8* // CHECK3-NEXT: [[TMP47:%.*]] = bitcast %"class.std::complex"* [[TMP44]] to i8* -// CHECK3-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !21 +// CHECK3-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 8, i1 false), !tbaa.struct !31 // CHECK3-NEXT: br label [[IFCONT6:%.*]] // CHECK3: else5: // CHECK3-NEXT: br label [[IFCONT6]] @@ -2980,13 +3000,13 @@ // // // CHECK3-LABEL: define {{[^@]+}}@_omp_reduction_inter_warp_copy_func -// CHECK3-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK3-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[DOTCNT_ADDR:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) -// CHECK3-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: [[NVPTX_TID:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() // CHECK3-NEXT: [[NVPTX_TID2:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() @@ -3007,7 +3027,7 @@ // CHECK3-NEXT: br i1 [[WARP_MASTER]], label [[THEN:%.*]], label [[ELSE:%.*]] // CHECK3: then: // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP9:%.*]] = bitcast i8* [[TMP8]] to i32* // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr i32, i32* [[TMP9]], i32 [[TMP5]] // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] @@ -3024,7 +3044,7 @@ // CHECK3: then2: // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_TID]] // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to i32* // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr i32, i32* [[TMP17]], i32 [[TMP5]] // CHECK3-NEXT: [[TMP19:%.*]] = load volatile i32, i32 addrspace(3)* [[TMP14]], align 4, !tbaa [[TBAA8]] @@ -3041,27 +3061,27 @@ // // // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper -// CHECK3-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK3-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 // CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8 -// CHECK3-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA19]] +// CHECK3-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA29]] // CHECK3-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK3-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) // CHECK3-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8 // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0 // CHECK3-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32** -// CHECK3-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 1 // CHECK3-NEXT: [[TMP7:%.*]] = bitcast i8** [[TMP6]] to i32** -// CHECK3-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 2 // CHECK3-NEXT: [[TMP10:%.*]] = bitcast i8** [[TMP9]] to %"class.std::complex"** -// CHECK3-NEXT: [[TMP11:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[TMP10]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex"* [[TMP11]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP11:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[TMP10]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex"* [[TMP11]]) #[[ATTR6]] // CHECK3-NEXT: ret void // // @@ -3077,7 +3097,7 @@ // CHECK3-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) // CHECK3-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK3-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: call void @__omp_outlined__2(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR5]] +// CHECK3-NEXT: call void @__omp_outlined__2(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTZERO_ADDR]]) #[[ATTR6]] // CHECK3-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true) // CHECK3-NEXT: ret void // CHECK3: worker.exit: @@ -3099,112 +3119,114 @@ // CHECK3-NEXT: [[REF_TMP:%.*]] = alloca double, align 8 // CHECK3-NEXT: [[REF_TMP2:%.*]] = alloca double, align 8 // CHECK3-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [3 x i8*], align 8 -// CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META32:![0-9]+]]) +// CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META35:![0-9]+]]) +// CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[ISTART:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK3-NEXT: [[ISTART_ON_STACK:%.*]] = bitcast i8* [[ISTART]] to i32* // CHECK3-NEXT: [[IEND:%.*]] = call i8* @__kmpc_alloc_shared(i64 4) // CHECK3-NEXT: [[IEND_ON_STACK:%.*]] = bitcast i8* [[IEND]] to i32* // CHECK3-NEXT: [[PARTIAL_SUM:%.*]] = call i8* @__kmpc_alloc_shared(i64 16) // CHECK3-NEXT: [[PARTIAL_SUM_ON_STACK:%.*]] = bitcast i8* [[PARTIAL_SUM]] to %"class.std::complex.0"* -// CHECK3-NEXT: [[TMP0:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP0]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP1:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP1]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR6]] // CHECK3-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP2:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP2]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR6]] // CHECK3-NEXT: store i32 99, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] // CHECK3-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] // CHECK3-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP5:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP6:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) -// CHECK3-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 99 +// CHECK3-NEXT: [[TMP7:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP7]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: call void @__kmpc_distribute_static_init_4(%struct.ident_t* @[[GLOB2]], i32 [[TMP9]], i32 92, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP10]], 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: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[COND_END]] // CHECK3: cond.end: -// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP9]], [[COND_FALSE]] ] +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP11]], [[COND_FALSE]] ] // CHECK3-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP10]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP12]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] // CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK3: omp.inner.for.cond.cleanup: // CHECK3-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK3: omp.inner.for.body: -// CHECK3-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP13]], 1 +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP15]], 1 // CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] // CHECK3-NEXT: store i32 [[ADD]], i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP14:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP14]]) #[[ATTR5]] -// CHECK3-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA22:![0-9]+]] -// CHECK3-NEXT: [[TMP15:%.*]] = bitcast double* [[REF_TMP2]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP15]]) #[[ATTR5]] -// CHECK3-NEXT: store double 0.000000e+00, double* [[REF_TMP2]], align 8, !tbaa [[TBAA22]] -// CHECK3-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM_ON_STACK]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR11]] -// CHECK3-NEXT: [[TMP16:%.*]] = bitcast double* [[REF_TMP2]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP16]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP17:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP17]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP18:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP18]], 4 +// CHECK3-NEXT: [[TMP16:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP16]]) #[[ATTR6]] +// CHECK3-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA37:![0-9]+]] +// CHECK3-NEXT: [[TMP17:%.*]] = bitcast double* [[REF_TMP2]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP17]]) #[[ATTR6]] +// CHECK3-NEXT: store double 0.000000e+00, double* [[REF_TMP2]], align 8, !tbaa [[TBAA37]] +// CHECK3-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM_ON_STACK]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP2]]) #[[ATTR13]] +// CHECK3-NEXT: [[TMP18:%.*]] = bitcast double* [[REF_TMP2]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP18]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP19:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP19]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[MUL3:%.*]] = mul nsw i32 [[TMP20]], 4 // CHECK3-NEXT: store i32 [[MUL3]], i32* [[ISTART_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP19:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[TMP21:%.*]] = load i32, i32* [[IB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP21]], 1 // CHECK3-NEXT: [[MUL5:%.*]] = mul nsw i32 [[ADD4]], 4 // CHECK3-NEXT: store i32 [[MUL5]], i32* [[IEND_ON_STACK]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP21:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* -// CHECK3-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 -// CHECK3-NEXT: [[TMP23:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* -// CHECK3-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 -// CHECK3-NEXT: [[TMP25:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM_ON_STACK]] to i8* -// CHECK3-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP26:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** -// CHECK3-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP7]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex.0"*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP26]], i64 3) +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0 +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast i32* [[ISTART_ON_STACK]] to i8* +// CHECK3-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1 +// CHECK3-NEXT: [[TMP25:%.*]] = bitcast i32* [[IEND_ON_STACK]] to i8* +// CHECK3-NEXT: store i8* [[TMP25]], i8** [[TMP24]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2 +// CHECK3-NEXT: [[TMP27:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM_ON_STACK]] to i8* +// CHECK3-NEXT: store i8* [[TMP27]], i8** [[TMP26]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP28:%.*]] = bitcast [3 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8** +// CHECK3-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB1]], i32 [[TMP9]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, i32*, i32*, %"class.std::complex.0"*)* @__omp_outlined__3 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__3_wrapper to i8*), i8** [[TMP28]], i64 3) // 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: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP27]], 1 +// CHECK3-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP29]], 1 // CHECK3-NEXT: store i32 [[ADD6]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: -// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP7]]) -// CHECK3-NEXT: [[TMP28:%.*]] = bitcast i32* [[IB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP29:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP29]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP30:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR5]] +// CHECK3-NEXT: call void @__kmpc_distribute_static_fini(%struct.ident_t* @[[GLOB2]], i32 [[TMP9]]) +// CHECK3-NEXT: [[TMP30:%.*]] = bitcast i32* [[IB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP30]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP31:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP31]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP32:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP32]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP33:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP33]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP34:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP34]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP35:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP35]]) #[[ATTR6]] // CHECK3-NEXT: call void @__kmpc_free_shared(i8* [[PARTIAL_SUM]], i64 16) // CHECK3-NEXT: call void @__kmpc_free_shared(i8* [[IEND]], i64 4) // CHECK3-NEXT: call void @__kmpc_free_shared(i8* [[ISTART]], i64 4) @@ -3212,18 +3234,18 @@ // // // CHECK3-LABEL: define {{[^@]+}}@_ZNSt7complexIdEC1ERKdS2_ -// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 // CHECK3-NEXT: [[__RE_ADDR:%.*]] = alloca double*, align 8 // CHECK3-NEXT: [[__IM_ADDR:%.*]] = alloca double*, align 8 -// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK3-NEXT: [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8 // CHECK3-NEXT: [[TMP1:%.*]] = load double*, double** [[__IM_ADDR]], align 8 -// CHECK3-NEXT: call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR11]] +// CHECK3-NEXT: call void @_ZNSt7complexIdEC2ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS1]], double* nonnull align 8 dereferenceable(8) [[TMP0]], double* nonnull align 8 dereferenceable(8) [[TMP1]]) #[[ATTR13]] // CHECK3-NEXT: ret void // // @@ -3253,224 +3275,226 @@ // CHECK3-NEXT: [[REF_TMP15:%.*]] = alloca double, align 8 // CHECK3-NEXT: [[REF_TMP16:%.*]] = alloca double, align 8 // CHECK3-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8 -// CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store %"class.std::complex.0"* [[PARTIAL_SUM]], %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP0:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP1:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP2:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP3:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP3]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP4:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP4]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP0]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP5]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP1]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[SUB:%.*]] = sub i32 [[TMP9]], [[TMP10]] +// CHECK3-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META39:![0-9]+]]) +// CHECK3-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META42:![0-9]+]]) +// CHECK3-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store i32* [[ISTART]], i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store i32* [[IEND]], i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store %"class.std::complex.0"* [[PARTIAL_SUM]], %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP2:%.*]] = load i32*, i32** [[ISTART_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP3:%.*]] = load i32*, i32** [[IEND_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP4:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[PARTIAL_SUM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP5:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP5]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP6:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP6]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP2]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP7]], i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP8:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP8]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP9]], i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP10:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP10]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[SUB:%.*]] = sub i32 [[TMP11]], [[TMP12]] // CHECK3-NEXT: [[SUB3:%.*]] = sub i32 [[SUB]], 1 // CHECK3-NEXT: [[ADD:%.*]] = add i32 [[SUB3]], 1 // CHECK3-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 1 // CHECK3-NEXT: [[SUB4:%.*]] = sub i32 [[DIV]], 1 // CHECK3-NEXT: store i32 [[SUB4]], i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP11:%.*]] = bitcast i32* [[I]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP11]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP12]], i32* [[I]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: [[TMP13:%.*]] = bitcast i32* [[I]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR5]] +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP13]]) #[[ATTR6]] // CHECK3-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP14]], [[TMP15]] +// CHECK3-NEXT: store i32 [[TMP14]], i32* [[I]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP15:%.*]] = bitcast i32* [[I]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP15]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_1]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP16]], [[TMP17]] // CHECK3-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]], label [[OMP_PRECOND_END:%.*]] // CHECK3: omp.precond.then: -// CHECK3-NEXT: [[TMP16:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP16]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP18:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP18]]) #[[ATTR6]] // CHECK3-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP17:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP17]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP18]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP19:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP19]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP21:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP21]]) #[[ATTR6]] // CHECK3-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP20:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP20]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP22:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP22]]) #[[ATTR6]] // CHECK3-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP21:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP21]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP22:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP22]]) #[[ATTR5]] -// CHECK3-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA22]] -// CHECK3-NEXT: [[TMP23:%.*]] = bitcast double* [[REF_TMP6]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP23]]) #[[ATTR5]] -// CHECK3-NEXT: store double 0.000000e+00, double* [[REF_TMP6]], align 8, !tbaa [[TBAA22]] -// CHECK3-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR11]] -// CHECK3-NEXT: [[TMP24:%.*]] = bitcast double* [[REF_TMP6]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP24]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP25:%.*]] = bitcast double* [[REF_TMP]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP25]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP26:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP26]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK3-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3]], i32 [[TMP28]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP23]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP24:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP24]]) #[[ATTR6]] +// CHECK3-NEXT: store double 0.000000e+00, double* [[REF_TMP]], align 8, !tbaa [[TBAA37]] +// CHECK3-NEXT: [[TMP25:%.*]] = bitcast double* [[REF_TMP6]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP25]]) #[[ATTR6]] +// CHECK3-NEXT: store double 0.000000e+00, double* [[REF_TMP6]], align 8, !tbaa [[TBAA37]] +// CHECK3-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], double* nonnull align 8 dereferenceable(8) [[REF_TMP]], double* nonnull align 8 dereferenceable(8) [[REF_TMP6]]) #[[ATTR13]] +// CHECK3-NEXT: [[TMP26:%.*]] = bitcast double* [[REF_TMP6]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP26]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP27:%.*]] = bitcast double* [[REF_TMP]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP27]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP28:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* [[TMP28]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP29:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP29]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: call void @__kmpc_for_static_init_4u(%struct.ident_t* @[[GLOB3]], i32 [[TMP30]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1) // CHECK3-NEXT: br label [[OMP_DISPATCH_COND:%.*]] // CHECK3: omp.dispatch.cond: -// CHECK3-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP29]], [[TMP30]] +// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CMP8:%.*]] = icmp ugt i32 [[TMP31]], [[TMP32]] // CHECK3-NEXT: br i1 [[CMP8]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] // CHECK3: cond.true: -// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[COND_END:%.*]] // CHECK3: cond.false: -// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[COND_END]] // CHECK3: cond.end: -// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ [[TMP31]], [[COND_TRUE]] ], [ [[TMP32]], [[COND_FALSE]] ] +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ [[TMP33]], [[COND_TRUE]] ], [ [[TMP34]], [[COND_FALSE]] ] // CHECK3-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: store i32 [[TMP33]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD9:%.*]] = add i32 [[TMP35]], 1 -// CHECK3-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP34]], [[ADD9]] +// CHECK3-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: store i32 [[TMP35]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD9:%.*]] = add i32 [[TMP37]], 1 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp ult i32 [[TMP36]], [[ADD9]] // CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_CLEANUP:%.*]] // CHECK3: omp.dispatch.cleanup: // CHECK3-NEXT: br label [[OMP_DISPATCH_END:%.*]] // CHECK3: omp.dispatch.body: // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD11:%.*]] = add i32 [[TMP37]], 1 -// CHECK3-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP36]], [[ADD11]] +// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD11:%.*]] = add i32 [[TMP39]], 1 +// CHECK3-NEXT: [[CMP12:%.*]] = icmp ult i32 [[TMP38]], [[ADD11]] // CHECK3-NEXT: br i1 [[CMP12]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_COND_CLEANUP:%.*]] // CHECK3: omp.inner.for.cond.cleanup: // CHECK3-NEXT: br label [[OMP_INNER_FOR_END:%.*]] // CHECK3: omp.inner.for.body: -// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[MUL:%.*]] = mul i32 [[TMP39]], 1 -// CHECK3-NEXT: [[ADD13:%.*]] = add i32 [[TMP38]], [[MUL]] +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[MUL:%.*]] = mul i32 [[TMP41]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add i32 [[TMP40]], [[MUL]] // CHECK3-NEXT: store i32 [[ADD13]], i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP40:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP40]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP41:%.*]] = bitcast double* [[REF_TMP15]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP41]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP42:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP42]] to double -// CHECK3-NEXT: store double [[CONV]], double* [[REF_TMP15]], align 8, !tbaa [[TBAA22]] -// CHECK3-NEXT: [[TMP43:%.*]] = bitcast double* [[REF_TMP16]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP43]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP42:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* [[TMP42]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP43:%.*]] = bitcast double* [[REF_TMP15]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP43]]) #[[ATTR6]] // CHECK3-NEXT: [[TMP44:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP44]] to double -// CHECK3-NEXT: store double [[CONV17]], double* [[REF_TMP16]], align 8, !tbaa [[TBAA22]] -// CHECK3-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR11]] -// CHECK3-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR11]] +// CHECK3-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP44]] to double +// CHECK3-NEXT: store double [[CONV]], double* [[REF_TMP15]], align 8, !tbaa [[TBAA37]] // CHECK3-NEXT: [[TMP45:%.*]] = bitcast double* [[REF_TMP16]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP45]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP46:%.*]] = bitcast double* [[REF_TMP15]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP46]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP47:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP47]]) #[[ATTR5]] +// CHECK3-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[TMP45]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP46:%.*]] = load i32, i32* [[I7]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[CONV17:%.*]] = sitofp i32 [[TMP46]] to double +// CHECK3-NEXT: store double [[CONV17]], double* [[REF_TMP16]], align 8, !tbaa [[TBAA37]] +// CHECK3-NEXT: call void @_ZNSt7complexIdEC1ERKdS2_(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]], double* nonnull align 8 dereferenceable(8) [[REF_TMP15]], double* nonnull align 8 dereferenceable(8) [[REF_TMP16]]) #[[ATTR13]] +// CHECK3-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[REF_TMP14]]) #[[ATTR13]] +// CHECK3-NEXT: [[TMP47:%.*]] = bitcast double* [[REF_TMP16]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP47]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP48:%.*]] = bitcast double* [[REF_TMP15]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* [[TMP48]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP49:%.*]] = bitcast %"class.std::complex.0"* [[REF_TMP14]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP49]]) #[[ATTR6]] // 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: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD18:%.*]] = add i32 [[TMP48]], 1 +// CHECK3-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD18:%.*]] = add i32 [[TMP50]], 1 // CHECK3-NEXT: store i32 [[ADD18]], i32* [[DOTOMP_IV]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK3: omp.dispatch.inc: -// CHECK3-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD19:%.*]] = add i32 [[TMP49]], [[TMP50]] -// CHECK3-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[ADD20:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK3-NEXT: [[ADD19:%.*]] = add i32 [[TMP51]], [[TMP52]] +// CHECK3-NEXT: store i32 [[ADD19]], i32* [[DOTOMP_LB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[ADD20:%.*]] = add i32 [[TMP53]], [[TMP54]] // CHECK3-NEXT: store i32 [[ADD20]], i32* [[DOTOMP_UB]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: br label [[OMP_DISPATCH_COND]] // CHECK3: omp.dispatch.end: -// CHECK3-NEXT: [[TMP53:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK3-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP54]]) // CHECK3-NEXT: [[TMP55:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 // CHECK3-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP55]], align 4, !tbaa [[TBAA8]] -// CHECK3-NEXT: [[TMP57:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP58:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* -// CHECK3-NEXT: store i8* [[TMP58]], i8** [[TMP57]], align 8 -// CHECK3-NEXT: [[TMP59:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* -// CHECK3-NEXT: [[TMP60:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP56]], i32 1, i64 8, i8* [[TMP59]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func5, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func6) -// CHECK3-NEXT: [[TMP61:%.*]] = icmp eq i32 [[TMP60]], 1 -// CHECK3-NEXT: br i1 [[TMP61]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] +// CHECK3-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB3]], i32 [[TMP56]]) +// CHECK3-NEXT: [[TMP57:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP58:%.*]] = load i32, i32* [[TMP57]], align 4, !tbaa [[TBAA8]] +// CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]], i64 0, i64 0 +// CHECK3-NEXT: [[TMP60:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* +// CHECK3-NEXT: store i8* [[TMP60]], i8** [[TMP59]], align 8 +// CHECK3-NEXT: [[TMP61:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8* +// CHECK3-NEXT: [[TMP62:%.*]] = call i32 @__kmpc_nvptx_parallel_reduce_nowait_v2(%struct.ident_t* @[[GLOB1]], i32 [[TMP58]], i32 1, i64 8, i8* [[TMP61]], void (i8*, i16, i16, i16)* @_omp_reduction_shuffle_and_reduce_func5, void (i8*, i32)* @_omp_reduction_inter_warp_copy_func6) +// CHECK3-NEXT: [[TMP63:%.*]] = icmp eq i32 [[TMP62]], 1 +// CHECK3-NEXT: br i1 [[TMP63]], label [[DOTOMP_REDUCTION_THEN:%.*]], label [[DOTOMP_REDUCTION_DONE:%.*]] // CHECK3: .omp.reduction.then: -// CHECK3-NEXT: [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP2]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR11]] -// CHECK3-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP56]]) +// CHECK3-NEXT: [[CALL21:%.*]] = call nonnull align 8 dereferenceable(16) %"class.std::complex.0"* @_ZNSt7complexIdEpLIdEERS0_RKS_IT_E(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP4]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[PARTIAL_SUM5]]) #[[ATTR13]] +// CHECK3-NEXT: call void @__kmpc_nvptx_end_reduce_nowait(i32 [[TMP58]]) // CHECK3-NEXT: br label [[DOTOMP_REDUCTION_DONE]] // CHECK3: .omp.reduction.done: -// CHECK3-NEXT: [[TMP62:%.*]] = bitcast i32* [[I7]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP62]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP63:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP63]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP64:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP65:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP65]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP64:%.*]] = bitcast i32* [[I7]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP64]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP65:%.*]] = bitcast %"class.std::complex.0"* [[PARTIAL_SUM5]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* [[TMP65]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP66:%.*]] = bitcast i32* [[DOTOMP_IS_LAST]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP66]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP67:%.*]] = bitcast i32* [[DOTOMP_STRIDE]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP67]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTOMP_UB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTOMP_LB]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR6]] // CHECK3-NEXT: br label [[OMP_PRECOND_END]] // CHECK3: omp.precond.end: -// CHECK3-NEXT: [[TMP68:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP68]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP69:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP69]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR5]] -// CHECK3-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* -// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP70:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_2]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP70]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP71:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_1]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP71]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP72:%.*]] = bitcast i32* [[DOTCAPTURE_EXPR_]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP72]]) #[[ATTR6]] +// CHECK3-NEXT: [[TMP73:%.*]] = bitcast i32* [[DOTOMP_IV]] to i8* +// CHECK3-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* [[TMP73]]) #[[ATTR6]] // CHECK3-NEXT: ret void // // // CHECK3-LABEL: define {{[^@]+}}@_ZNSt7complexIdEpLIdEERS0_RKS_IT_E -// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[__C:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], %"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[__C:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 // CHECK3-NEXT: [[__C_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 -// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store %"class.std::complex.0"* [[__C]], %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store %"class.std::complex.0"* [[__C]], %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 -// CHECK3-NEXT: [[TMP0:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP0]]) #[[ATTR11]] +// CHECK3-NEXT: [[TMP0:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[CALL:%.*]] = call double @_ZNKSt7complexIdE4realEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP0]]) #[[ATTR13]] // CHECK3-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24:![0-9]+]] +// CHECK3-NEXT: [[TMP1:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA44:![0-9]+]] // CHECK3-NEXT: [[ADD:%.*]] = fadd double [[TMP1]], [[CALL]] -// CHECK3-NEXT: store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA24]] -// CHECK3-NEXT: [[TMP2:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP2]]) #[[ATTR11]] +// CHECK3-NEXT: store double [[ADD]], double* [[__RE_]], align 8, !tbaa [[TBAA44]] +// CHECK3-NEXT: [[TMP2:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[__C_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[CALL2:%.*]] = call double @_ZNKSt7complexIdE4imagEv(%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[TMP2]]) #[[ATTR13]] // CHECK3-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26:![0-9]+]] +// CHECK3-NEXT: [[TMP3:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA46:![0-9]+]] // CHECK3-NEXT: [[ADD3:%.*]] = fadd double [[TMP3]], [[CALL2]] -// CHECK3-NEXT: store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]] +// CHECK3-NEXT: store double [[ADD3]], double* [[__IM_]], align 8, !tbaa [[TBAA46]] // CHECK3-NEXT: ret %"class.std::complex.0"* [[THIS1]] // // // CHECK3-LABEL: define {{[^@]+}}@_omp_reduction_shuffle_and_reduce_func5 -// CHECK3-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR6]] { +// CHECK3-SAME: (i8* [[TMP0:%.*]], i16 signext [[TMP1:%.*]], i16 signext [[TMP2:%.*]], i16 signext [[TMP3:%.*]]) #[[ATTR7]] { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca i16, align 2 @@ -3478,15 +3502,15 @@ // CHECK3-NEXT: [[DOTADDR3:%.*]] = alloca i16, align 2 // CHECK3-NEXT: [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST:%.*]] = alloca [1 x i8*], align 8 // CHECK3-NEXT: [[DOTOMP_REDUCTION_ELEMENT:%.*]] = alloca %"class.std::complex.0", align 8 -// CHECK3-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19]] -// CHECK3-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK3-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] -// CHECK3-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store i16 [[TMP1]], i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29]] +// CHECK3-NEXT: store i16 [[TMP2]], i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK3-NEXT: store i16 [[TMP3]], i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] +// CHECK3-NEXT: [[TMP4:%.*]] = load i8*, i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP5:%.*]] = bitcast i8* [[TMP4]] to [1 x i8*]* -// CHECK3-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA19]] -// CHECK3-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA19]] -// CHECK3-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA19]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i16, i16* [[DOTADDR1]], align 2, !tbaa [[TBAA29]] +// CHECK3-NEXT: [[TMP7:%.*]] = load i16, i16* [[DOTADDR2]], align 2, !tbaa [[TBAA29]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i16, i16* [[DOTADDR3]], align 2, !tbaa [[TBAA29]] // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP5]], i64 0, i64 0 // CHECK3-NEXT: [[TMP10:%.*]] = load i8*, i8** [[TMP9]], align 8 // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]], i64 0, i64 0 @@ -3517,7 +3541,7 @@ // CHECK3-NEXT: br label [[DOTSHUFFLE_PRE_COND]] // CHECK3: .shuffle.exit: // CHECK3-NEXT: [[TMP30:%.*]] = bitcast %"class.std::complex.0"* [[DOTOMP_REDUCTION_ELEMENT]] to i8* -// CHECK3-NEXT: store i8* [[TMP30]], i8** [[TMP11]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store i8* [[TMP30]], i8** [[TMP11]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP31:%.*]] = icmp eq i16 [[TMP8]], 0 // CHECK3-NEXT: [[TMP32:%.*]] = icmp eq i16 [[TMP8]], 1 // CHECK3-NEXT: [[TMP33:%.*]] = icmp ult i16 [[TMP6]], [[TMP7]] @@ -3534,7 +3558,7 @@ // CHECK3: then: // CHECK3-NEXT: [[TMP43:%.*]] = bitcast [1 x i8*]* [[TMP5]] to i8* // CHECK3-NEXT: [[TMP44:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_REMOTE_REDUCE_LIST]] to i8* -// CHECK3-NEXT: call void @"_omp$reduction$reduction_func4"(i8* [[TMP43]], i8* [[TMP44]]) #[[ATTR5]] +// CHECK3-NEXT: call void @"_omp$reduction$reduction_func4"(i8* [[TMP43]], i8* [[TMP44]]) #[[ATTR6]] // CHECK3-NEXT: br label [[IFCONT:%.*]] // CHECK3: else: // CHECK3-NEXT: br label [[IFCONT]] @@ -3552,7 +3576,7 @@ // CHECK3-NEXT: [[TMP53:%.*]] = bitcast i8* [[TMP51]] to %"class.std::complex.0"* // CHECK3-NEXT: [[TMP54:%.*]] = bitcast %"class.std::complex.0"* [[TMP53]] to i8* // CHECK3-NEXT: [[TMP55:%.*]] = bitcast %"class.std::complex.0"* [[TMP52]] to i8* -// CHECK3-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !27 +// CHECK3-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP54]], i8* align 8 [[TMP55]], i64 16, i1 false), !tbaa.struct !47 // CHECK3-NEXT: br label [[IFCONT6:%.*]] // CHECK3: else5: // CHECK3-NEXT: br label [[IFCONT6]] @@ -3561,13 +3585,13 @@ // // // CHECK3-LABEL: define {{[^@]+}}@_omp_reduction_inter_warp_copy_func6 -// CHECK3-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK3-SAME: (i8* [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[DOTADDR:%.*]] = alloca i8*, align 8 // CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[DOTCNT_ADDR:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[TMP2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) -// CHECK3-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store i8* [[TMP0]], i8** [[DOTADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: [[NVPTX_TID:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() // CHECK3-NEXT: [[NVPTX_TID2:%.*]] = call i32 @__kmpc_get_hardware_thread_id_in_block() @@ -3588,7 +3612,7 @@ // CHECK3-NEXT: br i1 [[WARP_MASTER]], label [[THEN:%.*]], label [[ELSE:%.*]] // CHECK3: then: // CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i8*, i8** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP9:%.*]] = bitcast i8* [[TMP8]] to i32* // CHECK3-NEXT: [[TMP10:%.*]] = getelementptr i32, i32* [[TMP9]], i32 [[TMP5]] // CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_WARP_ID]] @@ -3605,7 +3629,7 @@ // CHECK3: then2: // CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [32 x i32], [32 x i32] addrspace(3)* @__openmp_nvptx_data_transfer_temporary_storage, i64 0, i32 [[NVPTX_TID]] // CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[TMP4]], i64 0, i64 0 -// CHECK3-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP16:%.*]] = load i8*, i8** [[TMP15]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP17:%.*]] = bitcast i8* [[TMP16]] to i32* // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr i32, i32* [[TMP17]], i32 [[TMP5]] // CHECK3-NEXT: [[TMP19:%.*]] = load volatile i32, i32 addrspace(3)* [[TMP14]], align 4, !tbaa [[TBAA8]] @@ -3622,112 +3646,112 @@ // // // CHECK3-LABEL: define {{[^@]+}}@__omp_outlined__3_wrapper -// CHECK3-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR6]] { +// CHECK3-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR7]] { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[DOTADDR:%.*]] = alloca i16, align 2 // CHECK3-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4 // CHECK3-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8 -// CHECK3-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA19]] +// CHECK3-NEXT: store i16 [[TMP0]], i16* [[DOTADDR]], align 2, !tbaa [[TBAA29]] // CHECK3-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4, !tbaa [[TBAA8]] // CHECK3-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4 // CHECK3-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]]) // CHECK3-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[GLOBAL_ARGS]], align 8 // CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 0 // CHECK3-NEXT: [[TMP4:%.*]] = bitcast i8** [[TMP3]] to i32** -// CHECK3-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP5:%.*]] = load i32*, i32** [[TMP4]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 1 // CHECK3-NEXT: [[TMP7:%.*]] = bitcast i8** [[TMP6]] to i32** -// CHECK3-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32*, i32** [[TMP7]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds i8*, i8** [[TMP2]], i64 2 // CHECK3-NEXT: [[TMP10:%.*]] = bitcast i8** [[TMP9]] to %"class.std::complex.0"** -// CHECK3-NEXT: [[TMP11:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[TMP10]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: call void @__omp_outlined__3(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex.0"* [[TMP11]]) #[[ATTR5]] +// CHECK3-NEXT: [[TMP11:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[TMP10]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: call void @__omp_outlined__3(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]], i32* [[TMP5]], i32* [[TMP8]], %"class.std::complex.0"* [[TMP11]]) #[[ATTR6]] // CHECK3-NEXT: ret void // // // CHECK3-LABEL: define {{[^@]+}}@_ZNSt7complexIfEC2ERKfS2_ -// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]], float* nonnull align 4 dereferenceable(4) [[__RE:%.*]], float* nonnull align 4 dereferenceable(4) [[__IM:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 // CHECK3-NEXT: [[__RE_ADDR:%.*]] = alloca float*, align 8 // CHECK3-NEXT: [[__IM_ADDR:%.*]] = alloca float*, align 8 -// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store float* [[__RE]], float** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store float* [[__IM]], float** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK3-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP1:%.*]] = load float, float* [[TMP0]], align 4, !tbaa [[TBAA14]] -// CHECK3-NEXT: store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA16]] +// CHECK3-NEXT: [[TMP0:%.*]] = load float*, float** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP1:%.*]] = load float, float* [[TMP0]], align 4, !tbaa [[TBAA19]] +// CHECK3-NEXT: store float [[TMP1]], float* [[__RE_]], align 4, !tbaa [[TBAA26]] // CHECK3-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP2:%.*]] = load float*, float** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP3:%.*]] = load float, float* [[TMP2]], align 4, !tbaa [[TBAA14]] -// CHECK3-NEXT: store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA18]] +// CHECK3-NEXT: [[TMP2:%.*]] = load float*, float** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP3:%.*]] = load float, float* [[TMP2]], align 4, !tbaa [[TBAA19]] +// CHECK3-NEXT: store float [[TMP3]], float* [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK3-NEXT: ret void // // // CHECK3-LABEL: define {{[^@]+}}@_ZNKSt7complexIfE4realEv -// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 -// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK3-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA16]] +// CHECK3-NEXT: [[TMP0:%.*]] = load float, float* [[__RE_]], align 4, !tbaa [[TBAA26]] // CHECK3-NEXT: ret float [[TMP0]] // // // CHECK3-LABEL: define {{[^@]+}}@_ZNKSt7complexIfE4imagEv -// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex"* nonnull align 4 dereferenceable(8) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex"*, align 8 -// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex"* [[THIS]], %"class.std::complex"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex"*, %"class.std::complex"** [[THIS_ADDR]], align 8 // CHECK3-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex", %"class.std::complex"* [[THIS1]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA18]] +// CHECK3-NEXT: [[TMP0:%.*]] = load float, float* [[__IM_]], align 4, !tbaa [[TBAA28]] // CHECK3-NEXT: ret float [[TMP0]] // // // CHECK3-LABEL: define {{[^@]+}}@_ZNSt7complexIdEC2ERKdS2_ -// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]], double* nonnull align 8 dereferenceable(8) [[__RE:%.*]], double* nonnull align 8 dereferenceable(8) [[__IM:%.*]]) unnamed_addr #[[ATTR4]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 // CHECK3-NEXT: [[__RE_ADDR:%.*]] = alloca double*, align 8 // CHECK3-NEXT: [[__IM_ADDR:%.*]] = alloca double*, align 8 -// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store double* [[__RE]], double** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: store double* [[__IM]], double** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK3-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !tbaa [[TBAA22]] -// CHECK3-NEXT: store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA24]] +// CHECK3-NEXT: [[TMP0:%.*]] = load double*, double** [[__RE_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8, !tbaa [[TBAA37]] +// CHECK3-NEXT: store double [[TMP1]], double* [[__RE_]], align 8, !tbaa [[TBAA44]] // CHECK3-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP2:%.*]] = load double*, double** [[__IM_ADDR]], align 8, !tbaa [[TBAA12]] -// CHECK3-NEXT: [[TMP3:%.*]] = load double, double* [[TMP2]], align 8, !tbaa [[TBAA22]] -// CHECK3-NEXT: store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA26]] +// CHECK3-NEXT: [[TMP2:%.*]] = load double*, double** [[__IM_ADDR]], align 8, !tbaa [[TBAA15]] +// CHECK3-NEXT: [[TMP3:%.*]] = load double, double* [[TMP2]], align 8, !tbaa [[TBAA37]] +// CHECK3-NEXT: store double [[TMP3]], double* [[__IM_]], align 8, !tbaa [[TBAA46]] // CHECK3-NEXT: ret void // // // CHECK3-LABEL: define {{[^@]+}}@_ZNKSt7complexIdE4realEv -// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 -// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK3-NEXT: [[__RE_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA24]] +// CHECK3-NEXT: [[TMP0:%.*]] = load double, double* [[__RE_]], align 8, !tbaa [[TBAA44]] // CHECK3-NEXT: ret double [[TMP0]] // // // CHECK3-LABEL: define {{[^@]+}}@_ZNKSt7complexIdE4imagEv -// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR4]] comdat align 2 { +// CHECK3-SAME: (%"class.std::complex.0"* nonnull align 8 dereferenceable(16) [[THIS:%.*]]) #[[ATTR5]] comdat align 2 { // CHECK3-NEXT: entry: // CHECK3-NEXT: [[THIS_ADDR:%.*]] = alloca %"class.std::complex.0"*, align 8 -// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA12]] +// CHECK3-NEXT: store %"class.std::complex.0"* [[THIS]], %"class.std::complex.0"** [[THIS_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK3-NEXT: [[THIS1:%.*]] = load %"class.std::complex.0"*, %"class.std::complex.0"** [[THIS_ADDR]], align 8 // CHECK3-NEXT: [[__IM_:%.*]] = getelementptr inbounds %"class.std::complex.0", %"class.std::complex.0"* [[THIS1]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA26]] +// CHECK3-NEXT: [[TMP0:%.*]] = load double, double* [[__IM_]], align 8, !tbaa [[TBAA46]] // CHECK3-NEXT: ret double [[TMP0]] // Index: clang/test/OpenMP/parallel_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_codegen.cpp +++ clang/test/OpenMP/parallel_codegen.cpp @@ -311,105 +311,107 @@ // CHECK2-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8 // CHECK2-NEXT: store i32 0, i32* [[RETVAL]], align 4 // CHECK2-NEXT: store i32 [[ARGC]], i32* [[ARGC_ADDR]], align 4 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[ARGC_ADDR]], metadata [[META17:![0-9]+]], metadata !DIExpression()), !dbg [[DBG18:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[ARGC_ADDR]], metadata [[META18:![0-9]+]], metadata !DIExpression()), !dbg [[DBG19:![0-9]+]] // CHECK2-NEXT: store i8** [[ARGV]], i8*** [[ARGV_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGV_ADDR]], metadata [[META19:![0-9]+]], metadata !DIExpression()), !dbg [[DBG20:![0-9]+]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARGC_ADDR]], align 4, !dbg [[DBG21:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !dbg [[DBG22:![0-9]+]] -// CHECK2-NEXT: [[TMP2:%.*]] = call i8* @llvm.stacksave(), !dbg [[DBG22]] -// CHECK2-NEXT: store i8* [[TMP2]], i8** [[SAVED_STACK]], align 8, !dbg [[DBG22]] -// CHECK2-NEXT: [[VLA:%.*]] = alloca i32, i64 [[TMP1]], align 16, !dbg [[DBG22]] -// CHECK2-NEXT: store i64 [[TMP1]], i64* [[__VLA_EXPR0]], align 8, !dbg [[DBG22]] -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[__VLA_EXPR0]], metadata [[META23:![0-9]+]], metadata !DIExpression()), !dbg [[DBG25:![0-9]+]] -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[VLA]], metadata [[META26:![0-9]+]], metadata !DIExpression()), !dbg [[DBG30:![0-9]+]] -// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*), i64 [[TMP1]], i32* [[VLA]]), !dbg [[DBG31:![0-9]+]] -// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB5:[0-9]+]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i64 [[TMP1]]), !dbg [[DBG32:![0-9]+]] -// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB9:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*)* @.omp_outlined..8 to void (i32*, i32*, ...)*), i64 [[TMP1]], i32* [[VLA]]), !dbg [[DBG33:![0-9]+]] -// CHECK2-NEXT: [[TMP3:%.*]] = load i8**, i8*** [[ARGV_ADDR]], align 8, !dbg [[DBG34:![0-9]+]] -// CHECK2-NEXT: [[CALL:%.*]] = call i32 @_Z5tmainIPPcEiT_(i8** [[TMP3]]), !dbg [[DBG35:![0-9]+]] -// CHECK2-NEXT: store i32 [[CALL]], i32* [[RETVAL]], align 4, !dbg [[DBG36:![0-9]+]] -// CHECK2-NEXT: [[TMP4:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8, !dbg [[DBG37:![0-9]+]] -// CHECK2-NEXT: call void @llvm.stackrestore(i8* [[TMP4]]), !dbg [[DBG37]] -// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[RETVAL]], align 4, !dbg [[DBG37]] -// CHECK2-NEXT: ret i32 [[TMP5]], !dbg [[DBG37]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGV_ADDR]], metadata [[META20:![0-9]+]], metadata !DIExpression()), !dbg [[DBG21:![0-9]+]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARGC_ADDR]], align 4, !dbg [[DBG22:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !dbg [[DBG23:![0-9]+]] +// CHECK2-NEXT: [[TMP2:%.*]] = call i8* @llvm.stacksave(), !dbg [[DBG23]] +// CHECK2-NEXT: store i8* [[TMP2]], i8** [[SAVED_STACK]], align 8, !dbg [[DBG23]] +// CHECK2-NEXT: [[VLA:%.*]] = alloca i32, i64 [[TMP1]], align 16, !dbg [[DBG23]] +// CHECK2-NEXT: store i64 [[TMP1]], i64* [[__VLA_EXPR0]], align 8, !dbg [[DBG23]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[__VLA_EXPR0]], metadata [[META24:![0-9]+]], metadata !DIExpression()), !dbg [[DBG26:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[VLA]], metadata [[META27:![0-9]+]], metadata !DIExpression()), !dbg [[DBG31:![0-9]+]] +// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*), i64 [[TMP1]], i32* [[VLA]]), !dbg [[DBG32:![0-9]+]] +// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB5:[0-9]+]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i64 [[TMP1]]), !dbg [[DBG33:![0-9]+]] +// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB9:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*)* @.omp_outlined..8 to void (i32*, i32*, ...)*), i64 [[TMP1]], i32* [[VLA]]), !dbg [[DBG34:![0-9]+]] +// CHECK2-NEXT: [[TMP3:%.*]] = load i8**, i8*** [[ARGV_ADDR]], align 8, !dbg [[DBG35:![0-9]+]] +// CHECK2-NEXT: [[CALL:%.*]] = call i32 @_Z5tmainIPPcEiT_(i8** [[TMP3]]), !dbg [[DBG36:![0-9]+]] +// CHECK2-NEXT: store i32 [[CALL]], i32* [[RETVAL]], align 4, !dbg [[DBG37:![0-9]+]] +// CHECK2-NEXT: [[TMP4:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8, !dbg [[DBG38:![0-9]+]] +// CHECK2-NEXT: call void @llvm.stackrestore(i8* [[TMP4]]), !dbg [[DBG38]] +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[RETVAL]], align 4, !dbg [[DBG38]] +// CHECK2-NEXT: ret i32 [[TMP5]], !dbg [[DBG38]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined._debug__ -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG38:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3:[0-9]+]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG39:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META46:![0-9]+]], metadata !DIExpression()), !dbg [[DBG47:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META47:![0-9]+]], metadata !DIExpression()), !dbg [[DBG48:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META48:![0-9]+]], metadata !DIExpression()), !dbg [[DBG47]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META49:![0-9]+]], metadata !DIExpression()), !dbg [[DBG48]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META49:![0-9]+]], metadata !DIExpression()), !dbg [[DBG47]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META50:![0-9]+]], metadata !DIExpression()), !dbg [[DBG48]] // CHECK2-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META50:![0-9]+]], metadata !DIExpression()), !dbg [[DBG51:![0-9]+]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG52:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG52]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG53:![0-9]+]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !dbg [[DBG53]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META51:![0-9]+]], metadata !DIExpression()), !dbg [[DBG52:![0-9]+]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG53:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG53]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG54:![0-9]+]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !dbg [[DBG54]] // CHECK2-NEXT: invoke void @_Z3fooIiEvT_(i32 [[TMP2]]) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG52]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG53]] // CHECK2: invoke.cont: -// CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* @global, align 4, !dbg [[DBG54:![0-9]+]] -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG55:![0-9]+]] -// CHECK2-NEXT: store i32 [[TMP3]], i32* [[ARRAYIDX1]], align 4, !dbg [[DBG56:![0-9]+]] -// CHECK2-NEXT: ret void, !dbg [[DBG54]] +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* @global, align 4, !dbg [[DBG55:![0-9]+]] +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG56:![0-9]+]] +// CHECK2-NEXT: store i32 [[TMP3]], i32* [[ARRAYIDX1]], align 4, !dbg [[DBG57:![0-9]+]] +// CHECK2-NEXT: ret void, !dbg [[DBG55]] // CHECK2: terminate.lpad: // CHECK2-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } -// CHECK2-NEXT: catch i8* null, !dbg [[DBG52]] -// CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0, !dbg [[DBG52]] -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR7:[0-9]+]], !dbg [[DBG52]] -// CHECK2-NEXT: unreachable, !dbg [[DBG52]] +// CHECK2-NEXT: catch i8* null, !dbg [[DBG53]] +// CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0, !dbg [[DBG53]] +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR8:[0-9]+]], !dbg [[DBG53]] +// CHECK2-NEXT: unreachable, !dbg [[DBG53]] // // // CHECK2-LABEL: define {{[^@]+}}@_Z3fooIiEvT_ -// CHECK2-SAME: (i32 [[ARGC:%.*]]) #[[ATTR4:[0-9]+]] comdat !dbg [[DBG57:![0-9]+]] { +// CHECK2-SAME: (i32 [[ARGC:%.*]]) #[[ATTR4:[0-9]+]] comdat !dbg [[DBG58:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[ARGC_ADDR:%.*]] = alloca i32, align 4 // CHECK2-NEXT: store i32 [[ARGC]], i32* [[ARGC_ADDR]], align 4 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[ARGC_ADDR]], metadata [[META62:![0-9]+]], metadata !DIExpression()), !dbg [[DBG63:![0-9]+]] -// CHECK2-NEXT: ret void, !dbg [[DBG64:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[ARGC_ADDR]], metadata [[META63:![0-9]+]], metadata !DIExpression()), !dbg [[DBG64:![0-9]+]] +// CHECK2-NEXT: ret void, !dbg [[DBG65:![0-9]+]] // // // CHECK2-LABEL: define {{[^@]+}}@__clang_call_terminate // CHECK2-SAME: (i8* [[TMP0:%.*]]) #[[ATTR5:[0-9]+]] comdat { -// CHECK2-NEXT: [[TMP2:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP0]]) #[[ATTR6:[0-9]+]] -// CHECK2-NEXT: call void @_ZSt9terminatev() #[[ATTR7]] +// CHECK2-NEXT: [[TMP2:%.*]] = call i8* @__cxa_begin_catch(i8* [[TMP0]]) #[[ATTR7:[0-9]+]] +// CHECK2-NEXT: call void @_ZSt9terminatev() #[[ATTR8]] // CHECK2-NEXT: unreachable // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined. -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] !dbg [[DBG65:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] !dbg [[DBG66:![0-9]+]] !noalias !67 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META66:![0-9]+]], metadata !DIExpression()), !dbg [[DBG67:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META70:![0-9]+]], metadata !DIExpression()), !dbg [[DBG71:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META68:![0-9]+]], metadata !DIExpression()), !dbg [[DBG67]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META72:![0-9]+]], metadata !DIExpression()), !dbg [[DBG71]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META69:![0-9]+]], metadata !DIExpression()), !dbg [[DBG67]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META73:![0-9]+]], metadata !DIExpression()), !dbg [[DBG71]] // CHECK2-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META70:![0-9]+]], metadata !DIExpression()), !dbg [[DBG67]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG71:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG71]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG71]] -// CHECK2-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG71]] -// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG71]] -// CHECK2-NEXT: call void @.omp_outlined._debug__(i32* [[TMP2]], i32* [[TMP3]], i64 [[TMP0]], i32* [[TMP4]]) #[[ATTR6]], !dbg [[DBG71]] -// CHECK2-NEXT: ret void, !dbg [[DBG71]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META74:![0-9]+]], metadata !DIExpression()), !dbg [[DBG71]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG75:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG75]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG75]] +// CHECK2-NEXT: [[TMP3:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP2]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META67:![0-9]+]]), !dbg [[DBG75]] +// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG75]] +// CHECK2-NEXT: [[TMP5:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP4]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META67]]), !dbg [[DBG75]] +// CHECK2-NEXT: [[TMP6:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG75]] +// CHECK2-NEXT: call void @.omp_outlined._debug__(i32* [[TMP3]], i32* [[TMP5]], i64 [[TMP0]], i32* [[TMP6]]) #[[ATTR7]], !dbg [[DBG75]] +// CHECK2-NEXT: ret void, !dbg [[DBG75]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined._debug__.1 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]]) #[[ATTR3]] !dbg [[DBG74:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]]) #[[ATTR3]] !dbg [[DBG78:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -418,27 +420,27 @@ // CHECK2-NEXT: [[SAVED_STACK:%.*]] = alloca i8*, align 8 // CHECK2-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META77:![0-9]+]], metadata !DIExpression()), !dbg [[DBG78:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META81:![0-9]+]], metadata !DIExpression()), !dbg [[DBG82:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META79:![0-9]+]], metadata !DIExpression()), !dbg [[DBG78]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META83:![0-9]+]], metadata !DIExpression()), !dbg [[DBG82]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META80:![0-9]+]], metadata !DIExpression()), !dbg [[DBG78]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG81:![0-9]+]] -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[GLOBAL]], metadata [[META82:![0-9]+]], metadata !DIExpression()), !dbg [[DBG78]] -// CHECK2-NEXT: [[TMP1:%.*]] = call i8* @llvm.stacksave(), !dbg [[DBG81]] -// CHECK2-NEXT: store i8* [[TMP1]], i8** [[SAVED_STACK]], align 8, !dbg [[DBG81]] -// CHECK2-NEXT: [[VLA1:%.*]] = alloca i32, i64 [[TMP0]], align 16, !dbg [[DBG81]] -// CHECK2-NEXT: store i64 [[TMP0]], i64* [[__VLA_EXPR0]], align 8, !dbg [[DBG81]] -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[__VLA_EXPR0]], metadata [[META83:![0-9]+]], metadata !DIExpression()), !dbg [[DBG78]] -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[VLA1]], metadata [[META84:![0-9]+]], metadata !DIExpression()), !dbg [[DBG78]] -// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i64 [[TMP0]], i32* [[VLA1]], i32* [[GLOBAL]]), !dbg [[DBG81]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8, !dbg [[DBG85:![0-9]+]] -// CHECK2-NEXT: call void @llvm.stackrestore(i8* [[TMP2]]), !dbg [[DBG85]] -// CHECK2-NEXT: ret void, !dbg [[DBG87:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META84:![0-9]+]], metadata !DIExpression()), !dbg [[DBG82]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG85:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[GLOBAL]], metadata [[META86:![0-9]+]], metadata !DIExpression()), !dbg [[DBG82]] +// CHECK2-NEXT: [[TMP1:%.*]] = call i8* @llvm.stacksave(), !dbg [[DBG85]] +// CHECK2-NEXT: store i8* [[TMP1]], i8** [[SAVED_STACK]], align 8, !dbg [[DBG85]] +// CHECK2-NEXT: [[VLA1:%.*]] = alloca i32, i64 [[TMP0]], align 16, !dbg [[DBG85]] +// CHECK2-NEXT: store i64 [[TMP0]], i64* [[__VLA_EXPR0]], align 8, !dbg [[DBG85]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[__VLA_EXPR0]], metadata [[META87:![0-9]+]], metadata !DIExpression()), !dbg [[DBG82]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32* [[VLA1]], metadata [[META88:![0-9]+]], metadata !DIExpression()), !dbg [[DBG82]] +// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 3, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i64 [[TMP0]], i32* [[VLA1]], i32* [[GLOBAL]]), !dbg [[DBG85]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8, !dbg [[DBG89:![0-9]+]] +// CHECK2-NEXT: call void @llvm.stackrestore(i8* [[TMP2]]), !dbg [[DBG89]] +// CHECK2-NEXT: ret void, !dbg [[DBG91:![0-9]+]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined._debug__.2 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], i32* nonnull align 4 dereferenceable(4) [[GLOBAL:%.*]]) #[[ATTR3]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG88:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], i32* nonnull align 4 dereferenceable(4) [[GLOBAL:%.*]]) #[[ATTR3]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG92:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -446,37 +448,37 @@ // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[GLOBAL_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META91:![0-9]+]], metadata !DIExpression()), !dbg [[DBG92:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META95:![0-9]+]], metadata !DIExpression()), !dbg [[DBG96:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META93:![0-9]+]], metadata !DIExpression()), !dbg [[DBG92]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META97:![0-9]+]], metadata !DIExpression()), !dbg [[DBG96]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META94:![0-9]+]], metadata !DIExpression()), !dbg [[DBG92]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META98:![0-9]+]], metadata !DIExpression()), !dbg [[DBG96]] // CHECK2-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META95:![0-9]+]], metadata !DIExpression()), !dbg [[DBG96:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META99:![0-9]+]], metadata !DIExpression()), !dbg [[DBG100:![0-9]+]] // CHECK2-NEXT: store i32* [[GLOBAL]], i32** [[GLOBAL_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[GLOBAL_ADDR]], metadata [[META97:![0-9]+]], metadata !DIExpression()), !dbg [[DBG98:![0-9]+]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG99:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG99]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[GLOBAL_ADDR]], align 8, !dbg [[DBG99]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG100:![0-9]+]] -// CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !dbg [[DBG100]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[GLOBAL_ADDR]], metadata [[META101:![0-9]+]], metadata !DIExpression()), !dbg [[DBG102:![0-9]+]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG103:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG103]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[GLOBAL_ADDR]], align 8, !dbg [[DBG103]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG104:![0-9]+]] +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !dbg [[DBG104]] // CHECK2-NEXT: invoke void @_Z3fooIiEvT_(i32 [[TMP3]]) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG99]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG103]] // CHECK2: invoke.cont: -// CHECK2-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG101:![0-9]+]] -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG102:![0-9]+]] -// CHECK2-NEXT: store i32 [[TMP4]], i32* [[ARRAYIDX1]], align 4, !dbg [[DBG103:![0-9]+]] -// CHECK2-NEXT: ret void, !dbg [[DBG101]] +// CHECK2-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP2]], align 4, !dbg [[DBG105:![0-9]+]] +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG106:![0-9]+]] +// CHECK2-NEXT: store i32 [[TMP4]], i32* [[ARRAYIDX1]], align 4, !dbg [[DBG107:![0-9]+]] +// CHECK2-NEXT: ret void, !dbg [[DBG105]] // CHECK2: terminate.lpad: // CHECK2-NEXT: [[TMP5:%.*]] = landingpad { i8*, i32 } -// CHECK2-NEXT: catch i8* null, !dbg [[DBG99]] -// CHECK2-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0, !dbg [[DBG99]] -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR7]], !dbg [[DBG99]] -// CHECK2-NEXT: unreachable, !dbg [[DBG99]] +// CHECK2-NEXT: catch i8* null, !dbg [[DBG103]] +// CHECK2-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0, !dbg [[DBG103]] +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8]], !dbg [[DBG103]] +// CHECK2-NEXT: unreachable, !dbg [[DBG103]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..3 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], i32* nonnull align 4 dereferenceable(4) [[GLOBAL:%.*]]) #[[ATTR3]] !dbg [[DBG104:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], i32* nonnull align 4 dereferenceable(4) [[GLOBAL:%.*]]) #[[ATTR3]] !dbg [[DBG108:![0-9]+]] !noalias !109 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -484,166 +486,174 @@ // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[GLOBAL_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META105:![0-9]+]], metadata !DIExpression()), !dbg [[DBG106:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META112:![0-9]+]], metadata !DIExpression()), !dbg [[DBG113:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META107:![0-9]+]], metadata !DIExpression()), !dbg [[DBG106]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META114:![0-9]+]], metadata !DIExpression()), !dbg [[DBG113]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META108:![0-9]+]], metadata !DIExpression()), !dbg [[DBG106]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META115:![0-9]+]], metadata !DIExpression()), !dbg [[DBG113]] // CHECK2-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META109:![0-9]+]], metadata !DIExpression()), !dbg [[DBG106]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META116:![0-9]+]], metadata !DIExpression()), !dbg [[DBG113]] // CHECK2-NEXT: store i32* [[GLOBAL]], i32** [[GLOBAL_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[GLOBAL_ADDR]], metadata [[META110:![0-9]+]], metadata !DIExpression()), !dbg [[DBG106]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG111:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG111]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[GLOBAL_ADDR]], align 8, !dbg [[DBG111]] -// CHECK2-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG111]] -// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG111]] -// CHECK2-NEXT: [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG111]] -// CHECK2-NEXT: [[TMP6:%.*]] = load i32*, i32** [[GLOBAL_ADDR]], align 8, !dbg [[DBG111]] -// CHECK2-NEXT: call void @.omp_outlined._debug__.2(i32* [[TMP3]], i32* [[TMP4]], i64 [[TMP0]], i32* [[TMP5]], i32* [[TMP6]]) #[[ATTR6]], !dbg [[DBG111]] -// CHECK2-NEXT: ret void, !dbg [[DBG111]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[GLOBAL_ADDR]], metadata [[META117:![0-9]+]], metadata !DIExpression()), !dbg [[DBG113]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG118:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[GLOBAL_ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP4:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP3]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META109:![0-9]+]]), !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP5:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META109]]), !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP7:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: [[TMP8:%.*]] = load i32*, i32** [[GLOBAL_ADDR]], align 8, !dbg [[DBG118]] +// CHECK2-NEXT: call void @.omp_outlined._debug__.2(i32* [[TMP4]], i32* [[TMP6]], i64 [[TMP0]], i32* [[TMP7]], i32* [[TMP8]]) #[[ATTR7]], !dbg [[DBG118]] +// CHECK2-NEXT: ret void, !dbg [[DBG118]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..4 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]]) #[[ATTR3]] !dbg [[DBG112:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]]) #[[ATTR3]] !dbg [[DBG119:![0-9]+]] !noalias !120 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META113:![0-9]+]], metadata !DIExpression()), !dbg [[DBG114:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META123:![0-9]+]], metadata !DIExpression()), !dbg [[DBG124:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META115:![0-9]+]], metadata !DIExpression()), !dbg [[DBG114]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META125:![0-9]+]], metadata !DIExpression()), !dbg [[DBG124]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META116:![0-9]+]], metadata !DIExpression()), !dbg [[DBG114]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG117:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG117]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG117]] -// CHECK2-NEXT: call void @.omp_outlined._debug__.1(i32* [[TMP1]], i32* [[TMP2]], i64 [[TMP0]]) #[[ATTR6]], !dbg [[DBG117]] -// CHECK2-NEXT: ret void, !dbg [[DBG117]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META126:![0-9]+]], metadata !DIExpression()), !dbg [[DBG124]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG127:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG127]] +// CHECK2-NEXT: [[TMP2:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP1]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META120:![0-9]+]]), !dbg [[DBG127]] +// CHECK2-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG127]] +// CHECK2-NEXT: [[TMP4:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP3]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META120]]), !dbg [[DBG127]] +// CHECK2-NEXT: call void @.omp_outlined._debug__.1(i32* [[TMP2]], i32* [[TMP4]], i64 [[TMP0]]) #[[ATTR7]], !dbg [[DBG127]] +// CHECK2-NEXT: ret void, !dbg [[DBG127]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined._debug__.5 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] !dbg [[DBG118:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] !dbg [[DBG128:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META119:![0-9]+]], metadata !DIExpression()), !dbg [[DBG120:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META129:![0-9]+]], metadata !DIExpression()), !dbg [[DBG130:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META121:![0-9]+]], metadata !DIExpression()), !dbg [[DBG120]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META131:![0-9]+]], metadata !DIExpression()), !dbg [[DBG130]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META122:![0-9]+]], metadata !DIExpression()), !dbg [[DBG120]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META132:![0-9]+]], metadata !DIExpression()), !dbg [[DBG130]] // CHECK2-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META123:![0-9]+]], metadata !DIExpression()), !dbg [[DBG124:![0-9]+]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG125:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG125]] -// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB7:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*)* @.omp_outlined..7 to void (i32*, i32*, ...)*), i64 [[TMP0]], i32* [[TMP1]]), !dbg [[DBG125]] -// CHECK2-NEXT: ret void, !dbg [[DBG126:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META133:![0-9]+]], metadata !DIExpression()), !dbg [[DBG134:![0-9]+]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG135:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG135]] +// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB7:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*)* @.omp_outlined..7 to void (i32*, i32*, ...)*), i64 [[TMP0]], i32* [[TMP1]]), !dbg [[DBG135]] +// CHECK2-NEXT: ret void, !dbg [[DBG136:![0-9]+]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined._debug__.6 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG127:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG137:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META128:![0-9]+]], metadata !DIExpression()), !dbg [[DBG129:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META138:![0-9]+]], metadata !DIExpression()), !dbg [[DBG139:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META130:![0-9]+]], metadata !DIExpression()), !dbg [[DBG129]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META140:![0-9]+]], metadata !DIExpression()), !dbg [[DBG139]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META131:![0-9]+]], metadata !DIExpression()), !dbg [[DBG129]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META141:![0-9]+]], metadata !DIExpression()), !dbg [[DBG139]] // CHECK2-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META132:![0-9]+]], metadata !DIExpression()), !dbg [[DBG133:![0-9]+]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG134:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG134]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG135:![0-9]+]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !dbg [[DBG135]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META142:![0-9]+]], metadata !DIExpression()), !dbg [[DBG143:![0-9]+]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG144:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG144]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG145:![0-9]+]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !dbg [[DBG145]] // CHECK2-NEXT: invoke void @_Z3fooIiEvT_(i32 [[TMP2]]) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG134]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG144]] // CHECK2: invoke.cont: -// CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* @global, align 4, !dbg [[DBG136:![0-9]+]] -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG137:![0-9]+]] -// CHECK2-NEXT: store i32 [[TMP3]], i32* [[ARRAYIDX1]], align 4, !dbg [[DBG138:![0-9]+]] -// CHECK2-NEXT: ret void, !dbg [[DBG136]] +// CHECK2-NEXT: [[TMP3:%.*]] = load i32, i32* @global, align 4, !dbg [[DBG146:![0-9]+]] +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 1, !dbg [[DBG147:![0-9]+]] +// CHECK2-NEXT: store i32 [[TMP3]], i32* [[ARRAYIDX1]], align 4, !dbg [[DBG148:![0-9]+]] +// CHECK2-NEXT: ret void, !dbg [[DBG146]] // CHECK2: terminate.lpad: // CHECK2-NEXT: [[TMP4:%.*]] = landingpad { i8*, i32 } -// CHECK2-NEXT: catch i8* null, !dbg [[DBG134]] -// CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0, !dbg [[DBG134]] -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR7]], !dbg [[DBG134]] -// CHECK2-NEXT: unreachable, !dbg [[DBG134]] +// CHECK2-NEXT: catch i8* null, !dbg [[DBG144]] +// CHECK2-NEXT: [[TMP5:%.*]] = extractvalue { i8*, i32 } [[TMP4]], 0, !dbg [[DBG144]] +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP5]]) #[[ATTR8]], !dbg [[DBG144]] +// CHECK2-NEXT: unreachable, !dbg [[DBG144]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..7 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] !dbg [[DBG139:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] !dbg [[DBG149:![0-9]+]] !noalias !150 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META140:![0-9]+]], metadata !DIExpression()), !dbg [[DBG141:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META153:![0-9]+]], metadata !DIExpression()), !dbg [[DBG154:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META142:![0-9]+]], metadata !DIExpression()), !dbg [[DBG141]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META155:![0-9]+]], metadata !DIExpression()), !dbg [[DBG154]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META143:![0-9]+]], metadata !DIExpression()), !dbg [[DBG141]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META156:![0-9]+]], metadata !DIExpression()), !dbg [[DBG154]] // CHECK2-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META144:![0-9]+]], metadata !DIExpression()), !dbg [[DBG141]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG145:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG145]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG145]] -// CHECK2-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG145]] -// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG145]] -// CHECK2-NEXT: call void @.omp_outlined._debug__.6(i32* [[TMP2]], i32* [[TMP3]], i64 [[TMP0]], i32* [[TMP4]]) #[[ATTR6]], !dbg [[DBG145]] -// CHECK2-NEXT: ret void, !dbg [[DBG145]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META157:![0-9]+]], metadata !DIExpression()), !dbg [[DBG154]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG158:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG158]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG158]] +// CHECK2-NEXT: [[TMP3:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP2]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META150:![0-9]+]]), !dbg [[DBG158]] +// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG158]] +// CHECK2-NEXT: [[TMP5:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP4]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META150]]), !dbg [[DBG158]] +// CHECK2-NEXT: [[TMP6:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG158]] +// CHECK2-NEXT: call void @.omp_outlined._debug__.6(i32* [[TMP3]], i32* [[TMP5]], i64 [[TMP0]], i32* [[TMP6]]) #[[ATTR7]], !dbg [[DBG158]] +// CHECK2-NEXT: ret void, !dbg [[DBG158]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..8 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] !dbg [[DBG146:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i64 [[VLA:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] !dbg [[DBG159:![0-9]+]] !noalias !160 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META147:![0-9]+]], metadata !DIExpression()), !dbg [[DBG148:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META163:![0-9]+]], metadata !DIExpression()), !dbg [[DBG164:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META149:![0-9]+]], metadata !DIExpression()), !dbg [[DBG148]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META165:![0-9]+]], metadata !DIExpression()), !dbg [[DBG164]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META150:![0-9]+]], metadata !DIExpression()), !dbg [[DBG148]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META166:![0-9]+]], metadata !DIExpression()), !dbg [[DBG164]] // CHECK2-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META151:![0-9]+]], metadata !DIExpression()), !dbg [[DBG148]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG152:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG152]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG152]] -// CHECK2-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG152]] -// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG152]] -// CHECK2-NEXT: call void @.omp_outlined._debug__.5(i32* [[TMP2]], i32* [[TMP3]], i64 [[TMP0]], i32* [[TMP4]]) #[[ATTR6]], !dbg [[DBG152]] -// CHECK2-NEXT: ret void, !dbg [[DBG152]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META167:![0-9]+]], metadata !DIExpression()), !dbg [[DBG164]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG168:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG168]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG168]] +// CHECK2-NEXT: [[TMP3:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP2]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META160:![0-9]+]]), !dbg [[DBG168]] +// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG168]] +// CHECK2-NEXT: [[TMP5:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP4]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META160]]), !dbg [[DBG168]] +// CHECK2-NEXT: [[TMP6:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG168]] +// CHECK2-NEXT: call void @.omp_outlined._debug__.5(i32* [[TMP3]], i32* [[TMP5]], i64 [[TMP0]], i32* [[TMP6]]) #[[ATTR7]], !dbg [[DBG168]] +// CHECK2-NEXT: ret void, !dbg [[DBG168]] // // // CHECK2-LABEL: define {{[^@]+}}@_Z5tmainIPPcEiT_ -// CHECK2-SAME: (i8** [[ARGC:%.*]]) #[[ATTR4]] comdat !dbg [[DBG153:![0-9]+]] { +// CHECK2-SAME: (i8** [[ARGC:%.*]]) #[[ATTR4]] comdat !dbg [[DBG169:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[ARGC_ADDR:%.*]] = alloca i8**, align 8 // CHECK2-NEXT: store i8** [[ARGC]], i8*** [[ARGC_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGC_ADDR]], metadata [[META158:![0-9]+]], metadata !DIExpression()), !dbg [[DBG159:![0-9]+]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i8**, i8*** [[ARGC_ADDR]], align 8, !dbg [[DBG160:![0-9]+]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8*, i8** [[TMP0]], i64 0, !dbg [[DBG160]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i8*, i8** [[ARRAYIDX]], align 8, !dbg [[DBG160]] -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 0, !dbg [[DBG160]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i8, i8* [[ARRAYIDX1]], align 1, !dbg [[DBG160]] -// CHECK2-NEXT: [[TMP3:%.*]] = zext i8 [[TMP2]] to i64, !dbg [[DBG161:![0-9]+]] -// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB11:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i8***, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i8*** [[ARGC_ADDR]], i64 [[TMP3]]), !dbg [[DBG162:![0-9]+]] -// CHECK2-NEXT: ret i32 0, !dbg [[DBG163:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGC_ADDR]], metadata [[META174:![0-9]+]], metadata !DIExpression()), !dbg [[DBG175:![0-9]+]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i8**, i8*** [[ARGC_ADDR]], align 8, !dbg [[DBG176:![0-9]+]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8*, i8** [[TMP0]], i64 0, !dbg [[DBG176]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i8*, i8** [[ARRAYIDX]], align 8, !dbg [[DBG176]] +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 0, !dbg [[DBG176]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i8, i8* [[ARRAYIDX1]], align 1, !dbg [[DBG176]] +// CHECK2-NEXT: [[TMP3:%.*]] = zext i8 [[TMP2]] to i64, !dbg [[DBG177:![0-9]+]] +// CHECK2-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB11:[0-9]+]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i8***, i64)* @.omp_outlined..10 to void (i32*, i32*, ...)*), i8*** [[ARGC_ADDR]], i64 [[TMP3]]), !dbg [[DBG178:![0-9]+]] +// CHECK2-NEXT: ret i32 0, !dbg [[DBG179:![0-9]+]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined._debug__.9 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i8*** nonnull align 8 dereferenceable(8) [[ARGC:%.*]], i64 [[VLA:%.*]]) #[[ATTR3]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG164:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i8*** nonnull align 8 dereferenceable(8) [[ARGC:%.*]], i64 [[VLA:%.*]]) #[[ATTR3]] personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg [[DBG180:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -651,64 +661,66 @@ // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: [[VAR:%.*]] = alloca double*, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META168:![0-9]+]], metadata !DIExpression()), !dbg [[DBG169:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META184:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META170:![0-9]+]], metadata !DIExpression()), !dbg [[DBG169]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META186:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185]] // CHECK2-NEXT: store i8*** [[ARGC]], i8**** [[ARGC_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8**** [[ARGC_ADDR]], metadata [[META171:![0-9]+]], metadata !DIExpression()), !dbg [[DBG172:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8**** [[ARGC_ADDR]], metadata [[META187:![0-9]+]], metadata !DIExpression()), !dbg [[DBG188:![0-9]+]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META173:![0-9]+]], metadata !DIExpression()), !dbg [[DBG169]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i8***, i8**** [[ARGC_ADDR]], align 8, !dbg [[DBG174:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG174]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[TMP0]], align 8, !dbg [[DBG175:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META189:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i8***, i8**** [[ARGC_ADDR]], align 8, !dbg [[DBG190:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG190]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[TMP0]], align 8, !dbg [[DBG191:![0-9]+]] // CHECK2-NEXT: invoke void @_Z3fooIPPcEvT_(i8** [[TMP2]]) -// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG177:![0-9]+]] +// CHECK2-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TERMINATE_LPAD:%.*]], !dbg [[DBG193:![0-9]+]] // CHECK2: invoke.cont: -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata double** [[VAR]], metadata [[META178:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185:![0-9]+]] -// CHECK2-NEXT: [[TMP3:%.*]] = load double*, double** [[VAR]], align 8, !dbg [[DBG186:![0-9]+]] -// CHECK2-NEXT: [[TMP4:%.*]] = mul nsw i64 0, [[TMP1]], !dbg [[DBG186]] -// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, double* [[TMP3]], i64 [[TMP4]], !dbg [[DBG186]] -// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX]], i64 0, !dbg [[DBG186]] -// CHECK2-NEXT: ret void, !dbg [[DBG187:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata double** [[VAR]], metadata [[META194:![0-9]+]], metadata !DIExpression()), !dbg [[DBG201:![0-9]+]] +// CHECK2-NEXT: [[TMP3:%.*]] = load double*, double** [[VAR]], align 8, !dbg [[DBG202:![0-9]+]] +// CHECK2-NEXT: [[TMP4:%.*]] = mul nsw i64 0, [[TMP1]], !dbg [[DBG202]] +// CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, double* [[TMP3]], i64 [[TMP4]], !dbg [[DBG202]] +// CHECK2-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX]], i64 0, !dbg [[DBG202]] +// CHECK2-NEXT: ret void, !dbg [[DBG203:![0-9]+]] // CHECK2: terminate.lpad: // CHECK2-NEXT: [[TMP5:%.*]] = landingpad { i8*, i32 } -// CHECK2-NEXT: catch i8* null, !dbg [[DBG177]] -// CHECK2-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0, !dbg [[DBG177]] -// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR7]], !dbg [[DBG177]] -// CHECK2-NEXT: unreachable, !dbg [[DBG177]] +// CHECK2-NEXT: catch i8* null, !dbg [[DBG193]] +// CHECK2-NEXT: [[TMP6:%.*]] = extractvalue { i8*, i32 } [[TMP5]], 0, !dbg [[DBG193]] +// CHECK2-NEXT: call void @__clang_call_terminate(i8* [[TMP6]]) #[[ATTR8]], !dbg [[DBG193]] +// CHECK2-NEXT: unreachable, !dbg [[DBG193]] // // // CHECK2-LABEL: define {{[^@]+}}@_Z3fooIPPcEvT_ -// CHECK2-SAME: (i8** [[ARGC:%.*]]) #[[ATTR4]] comdat !dbg [[DBG188:![0-9]+]] { +// CHECK2-SAME: (i8** [[ARGC:%.*]]) #[[ATTR4]] comdat !dbg [[DBG204:![0-9]+]] { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[ARGC_ADDR:%.*]] = alloca i8**, align 8 // CHECK2-NEXT: store i8** [[ARGC]], i8*** [[ARGC_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGC_ADDR]], metadata [[META191:![0-9]+]], metadata !DIExpression()), !dbg [[DBG192:![0-9]+]] -// CHECK2-NEXT: ret void, !dbg [[DBG193:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGC_ADDR]], metadata [[META207:![0-9]+]], metadata !DIExpression()), !dbg [[DBG208:![0-9]+]] +// CHECK2-NEXT: ret void, !dbg [[DBG209:![0-9]+]] // // // CHECK2-LABEL: define {{[^@]+}}@.omp_outlined..10 -// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i8*** nonnull align 8 dereferenceable(8) [[ARGC:%.*]], i64 [[VLA:%.*]]) #[[ATTR3]] !dbg [[DBG194:![0-9]+]] { +// CHECK2-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], i8*** nonnull align 8 dereferenceable(8) [[ARGC:%.*]], i64 [[VLA:%.*]]) #[[ATTR3]] !dbg [[DBG210:![0-9]+]] !noalias !211 { // CHECK2-NEXT: entry: // CHECK2-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK2-NEXT: [[ARGC_ADDR:%.*]] = alloca i8***, align 8 // CHECK2-NEXT: [[VLA_ADDR:%.*]] = alloca i64, align 8 // CHECK2-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META195:![0-9]+]], metadata !DIExpression()), !dbg [[DBG196:![0-9]+]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META214:![0-9]+]], metadata !DIExpression()), !dbg [[DBG215:![0-9]+]] // CHECK2-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META197:![0-9]+]], metadata !DIExpression()), !dbg [[DBG196]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META216:![0-9]+]], metadata !DIExpression()), !dbg [[DBG215]] // CHECK2-NEXT: store i8*** [[ARGC]], i8**** [[ARGC_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8**** [[ARGC_ADDR]], metadata [[META198:![0-9]+]], metadata !DIExpression()), !dbg [[DBG196]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i8**** [[ARGC_ADDR]], metadata [[META217:![0-9]+]], metadata !DIExpression()), !dbg [[DBG215]] // CHECK2-NEXT: store i64 [[VLA]], i64* [[VLA_ADDR]], align 8 -// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META199:![0-9]+]], metadata !DIExpression()), !dbg [[DBG196]] -// CHECK2-NEXT: [[TMP0:%.*]] = load i8***, i8**** [[ARGC_ADDR]], align 8, !dbg [[DBG200:![0-9]+]] -// CHECK2-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG200]] -// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG200]] -// CHECK2-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG200]] -// CHECK2-NEXT: [[TMP4:%.*]] = load i8***, i8**** [[ARGC_ADDR]], align 8, !dbg [[DBG200]] -// CHECK2-NEXT: call void @.omp_outlined._debug__.9(i32* [[TMP2]], i32* [[TMP3]], i8*** [[TMP4]], i64 [[TMP1]]) #[[ATTR6]], !dbg [[DBG200]] -// CHECK2-NEXT: ret void, !dbg [[DBG200]] +// CHECK2-NEXT: call void @llvm.dbg.declare(metadata i64* [[VLA_ADDR]], metadata [[META218:![0-9]+]], metadata !DIExpression()), !dbg [[DBG215]] +// CHECK2-NEXT: [[TMP0:%.*]] = load i8***, i8**** [[ARGC_ADDR]], align 8, !dbg [[DBG219:![0-9]+]] +// CHECK2-NEXT: [[TMP1:%.*]] = load i64, i64* [[VLA_ADDR]], align 8, !dbg [[DBG219]] +// CHECK2-NEXT: [[TMP2:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG219]] +// CHECK2-NEXT: [[TMP3:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP2]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META211:![0-9]+]]), !dbg [[DBG219]] +// CHECK2-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG219]] +// CHECK2-NEXT: [[TMP5:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP4]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META211]]), !dbg [[DBG219]] +// CHECK2-NEXT: [[TMP6:%.*]] = load i8***, i8**** [[ARGC_ADDR]], align 8, !dbg [[DBG219]] +// CHECK2-NEXT: call void @.omp_outlined._debug__.9(i32* [[TMP3]], i32* [[TMP5]], i8*** [[TMP6]], i64 [[TMP1]]) #[[ATTR7]], !dbg [[DBG219]] +// CHECK2-NEXT: ret void, !dbg [[DBG219]] // // // CHECK3-LABEL: define {{[^@]+}}@main @@ -841,36 +853,36 @@ // CHECK4-NEXT: [[__VLA_EXPR0:%.*]] = alloca i64, align 8 // CHECK4-NEXT: store i32 0, i32* [[RETVAL]], align 4 // CHECK4-NEXT: store i32 [[ARGC]], i32* [[ARGC_ADDR]], align 4 -// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i32* [[ARGC_ADDR]], metadata [[META17:![0-9]+]], metadata !DIExpression()), !dbg [[DBG18:![0-9]+]] +// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i32* [[ARGC_ADDR]], metadata [[META18:![0-9]+]], metadata !DIExpression()), !dbg [[DBG19:![0-9]+]] // CHECK4-NEXT: store i8** [[ARGV]], i8*** [[ARGV_ADDR]], align 8 -// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGV_ADDR]], metadata [[META19:![0-9]+]], metadata !DIExpression()), !dbg [[DBG18]] -// CHECK4-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARGC_ADDR]], align 4, !dbg [[DBG20:![0-9]+]] -// CHECK4-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !dbg [[DBG20]] -// CHECK4-NEXT: [[TMP2:%.*]] = call i8* @llvm.stacksave(), !dbg [[DBG20]] -// CHECK4-NEXT: store i8* [[TMP2]], i8** [[SAVED_STACK]], align 8, !dbg [[DBG20]] -// CHECK4-NEXT: [[VLA:%.*]] = alloca i32, i64 [[TMP1]], align 16, !dbg [[DBG20]] -// CHECK4-NEXT: store i64 [[TMP1]], i64* [[__VLA_EXPR0]], align 8, !dbg [[DBG20]] -// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i64* [[__VLA_EXPR0]], metadata [[META21:![0-9]+]], metadata !DIExpression()), !dbg [[DBG23:![0-9]+]] -// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i32* [[VLA]], metadata [[META24:![0-9]+]], metadata !DIExpression()), !dbg [[DBG20]] -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1:[0-9]+]]), !dbg [[DBG28:![0-9]+]] +// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGV_ADDR]], metadata [[META20:![0-9]+]], metadata !DIExpression()), !dbg [[DBG19]] +// CHECK4-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARGC_ADDR]], align 4, !dbg [[DBG21:![0-9]+]] +// CHECK4-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64, !dbg [[DBG21]] +// CHECK4-NEXT: [[TMP2:%.*]] = call i8* @llvm.stacksave(), !dbg [[DBG21]] +// CHECK4-NEXT: store i8* [[TMP2]], i8** [[SAVED_STACK]], align 8, !dbg [[DBG21]] +// CHECK4-NEXT: [[VLA:%.*]] = alloca i32, i64 [[TMP1]], align 16, !dbg [[DBG21]] +// CHECK4-NEXT: store i64 [[TMP1]], i64* [[__VLA_EXPR0]], align 8, !dbg [[DBG21]] +// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i64* [[__VLA_EXPR0]], metadata [[META22:![0-9]+]], metadata !DIExpression()), !dbg [[DBG24:![0-9]+]] +// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i32* [[VLA]], metadata [[META25:![0-9]+]], metadata !DIExpression()), !dbg [[DBG21]] +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1:[0-9]+]]), !dbg [[DBG29:![0-9]+]] // CHECK4-NEXT: br label [[OMP_PARALLEL:%.*]] // CHECK4: omp_parallel: -// CHECK4-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @main..omp_par to void (i32*, i32*, ...)*), i32* [[VLA]]), !dbg [[DBG29:![0-9]+]] +// CHECK4-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* @main..omp_par to void (i32*, i32*, ...)*), i32* [[VLA]]), !dbg [[DBG30:![0-9]+]] // CHECK4-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]] // CHECK4: omp.par.outlined.exit: // CHECK4-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]] // CHECK4: omp.par.exit.split: -// CHECK4-NEXT: [[TMP3:%.*]] = load i8**, i8*** [[ARGV_ADDR]], align 8, !dbg [[DBG30:![0-9]+]] -// CHECK4-NEXT: [[CALL:%.*]] = call i32 @_Z5tmainIPPcEiT_(i8** [[TMP3]]), !dbg [[DBG30]] -// CHECK4-NEXT: store i32 [[CALL]], i32* [[RETVAL]], align 4, !dbg [[DBG30]] -// CHECK4-NEXT: [[TMP4:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8, !dbg [[DBG31:![0-9]+]] -// CHECK4-NEXT: call void @llvm.stackrestore(i8* [[TMP4]]), !dbg [[DBG31]] -// CHECK4-NEXT: [[TMP5:%.*]] = load i32, i32* [[RETVAL]], align 4, !dbg [[DBG31]] -// CHECK4-NEXT: ret i32 [[TMP5]], !dbg [[DBG31]] +// CHECK4-NEXT: [[TMP3:%.*]] = load i8**, i8*** [[ARGV_ADDR]], align 8, !dbg [[DBG31:![0-9]+]] +// CHECK4-NEXT: [[CALL:%.*]] = call i32 @_Z5tmainIPPcEiT_(i8** [[TMP3]]), !dbg [[DBG31]] +// CHECK4-NEXT: store i32 [[CALL]], i32* [[RETVAL]], align 4, !dbg [[DBG31]] +// CHECK4-NEXT: [[TMP4:%.*]] = load i8*, i8** [[SAVED_STACK]], align 8, !dbg [[DBG32:![0-9]+]] +// CHECK4-NEXT: call void @llvm.stackrestore(i8* [[TMP4]]), !dbg [[DBG32]] +// CHECK4-NEXT: [[TMP5:%.*]] = load i32, i32* [[RETVAL]], align 4, !dbg [[DBG32]] +// CHECK4-NEXT: ret i32 [[TMP5]], !dbg [[DBG32]] // // // CHECK4-LABEL: define {{[^@]+}}@main..omp_par -// CHECK4-SAME: (i32* noalias [[TID_ADDR:%.*]], i32* noalias [[ZERO_ADDR:%.*]], i32* [[VLA:%.*]]) #[[ATTR1:[0-9]+]] !dbg [[DBG32:![0-9]+]] { +// CHECK4-SAME: (i32* noalias [[TID_ADDR:%.*]], i32* noalias [[ZERO_ADDR:%.*]], i32* [[VLA:%.*]]) #[[ATTR1:[0-9]+]] !dbg [[DBG33:![0-9]+]] { // CHECK4-NEXT: omp.par.entry: // CHECK4-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4 // CHECK4-NEXT: [[TMP0:%.*]] = load i32, i32* [[TID_ADDR]], align 4 @@ -878,55 +890,55 @@ // CHECK4-NEXT: [[TID:%.*]] = load i32, i32* [[TID_ADDR_LOCAL]], align 4 // CHECK4-NEXT: br label [[OMP_PAR_REGION:%.*]] // CHECK4: omp.par.region: -// CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[VLA]], i64 1, !dbg [[DBG34:![0-9]+]] -// CHECK4-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !dbg [[DBG34]] -// CHECK4-NEXT: call void @_Z3fooIiEvT_(i32 [[TMP1]]), !dbg [[DBG34]] -// CHECK4-NEXT: [[TMP2:%.*]] = load i32, i32* @global, align 4, !dbg [[DBG34]] -// CHECK4-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[VLA]], i64 1, !dbg [[DBG34]] -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[ARRAYIDX1]], align 4, !dbg [[DBG34]] -// CHECK4-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]], !dbg [[DBG34]] +// CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[VLA]], i64 1, !dbg [[DBG35:![0-9]+]] +// CHECK4-NEXT: [[TMP1:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !dbg [[DBG35]] +// CHECK4-NEXT: call void @_Z3fooIiEvT_(i32 [[TMP1]]), !dbg [[DBG35]] +// CHECK4-NEXT: [[TMP2:%.*]] = load i32, i32* @global, align 4, !dbg [[DBG35]] +// CHECK4-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, i32* [[VLA]], i64 1, !dbg [[DBG35]] +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[ARRAYIDX1]], align 4, !dbg [[DBG35]] +// CHECK4-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]], !dbg [[DBG35]] // CHECK4: omp.par.pre_finalize: -// CHECK4-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]], !dbg [[DBG34]] +// CHECK4-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]], !dbg [[DBG35]] // CHECK4: omp.par.outlined.exit.exitStub: // CHECK4-NEXT: ret void // // // CHECK4-LABEL: define {{[^@]+}}@_Z3fooIiEvT_ -// CHECK4-SAME: (i32 [[ARGC:%.*]]) #[[ATTR5:[0-9]+]] comdat !dbg [[DBG35:![0-9]+]] { +// CHECK4-SAME: (i32 [[ARGC:%.*]]) #[[ATTR5:[0-9]+]] comdat !dbg [[DBG36:![0-9]+]] { // CHECK4-NEXT: entry: // CHECK4-NEXT: [[ARGC_ADDR:%.*]] = alloca i32, align 4 // CHECK4-NEXT: store i32 [[ARGC]], i32* [[ARGC_ADDR]], align 4 -// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i32* [[ARGC_ADDR]], metadata [[META40:![0-9]+]], metadata !DIExpression()), !dbg [[DBG41:![0-9]+]] -// CHECK4-NEXT: ret void, !dbg [[DBG41]] +// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i32* [[ARGC_ADDR]], metadata [[META41:![0-9]+]], metadata !DIExpression()), !dbg [[DBG42:![0-9]+]] +// CHECK4-NEXT: ret void, !dbg [[DBG42]] // // // CHECK4-LABEL: define {{[^@]+}}@_Z5tmainIPPcEiT_ -// CHECK4-SAME: (i8** [[ARGC:%.*]]) #[[ATTR6:[0-9]+]] comdat !dbg [[DBG44:![0-9]+]] { +// CHECK4-SAME: (i8** [[ARGC:%.*]]) #[[ATTR6:[0-9]+]] comdat !dbg [[DBG45:![0-9]+]] { // CHECK4-NEXT: entry: // CHECK4-NEXT: [[DOTRELOADED:%.*]] = alloca i64, align 8 // CHECK4-NEXT: [[ARGC_ADDR:%.*]] = alloca i8**, align 8 // CHECK4-NEXT: store i8** [[ARGC]], i8*** [[ARGC_ADDR]], align 8 -// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGC_ADDR]], metadata [[META49:![0-9]+]], metadata !DIExpression()), !dbg [[DBG50:![0-9]+]] -// CHECK4-NEXT: [[TMP0:%.*]] = load i8**, i8*** [[ARGC_ADDR]], align 8, !dbg [[DBG51:![0-9]+]] -// CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8*, i8** [[TMP0]], i64 0, !dbg [[DBG51]] -// CHECK4-NEXT: [[TMP1:%.*]] = load i8*, i8** [[ARRAYIDX]], align 8, !dbg [[DBG51]] -// CHECK4-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 0, !dbg [[DBG51]] -// CHECK4-NEXT: [[TMP2:%.*]] = load i8, i8* [[ARRAYIDX1]], align 1, !dbg [[DBG51]] -// CHECK4-NEXT: [[TMP3:%.*]] = zext i8 [[TMP2]] to i64, !dbg [[DBG51]] -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB3:[0-9]+]]), !dbg [[DBG52:![0-9]+]] +// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGC_ADDR]], metadata [[META50:![0-9]+]], metadata !DIExpression()), !dbg [[DBG51:![0-9]+]] +// CHECK4-NEXT: [[TMP0:%.*]] = load i8**, i8*** [[ARGC_ADDR]], align 8, !dbg [[DBG52:![0-9]+]] +// CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8*, i8** [[TMP0]], i64 0, !dbg [[DBG52]] +// CHECK4-NEXT: [[TMP1:%.*]] = load i8*, i8** [[ARRAYIDX]], align 8, !dbg [[DBG52]] +// CHECK4-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 0, !dbg [[DBG52]] +// CHECK4-NEXT: [[TMP2:%.*]] = load i8, i8* [[ARRAYIDX1]], align 1, !dbg [[DBG52]] +// CHECK4-NEXT: [[TMP3:%.*]] = zext i8 [[TMP2]] to i64, !dbg [[DBG52]] +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB3:[0-9]+]]), !dbg [[DBG53:![0-9]+]] // CHECK4-NEXT: store i64 [[TMP3]], i64* [[DOTRELOADED]], align 8 // CHECK4-NEXT: br label [[OMP_PARALLEL:%.*]] // CHECK4: omp_parallel: -// CHECK4-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64*, i8***)* @_Z5tmainIPPcEiT_..omp_par to void (i32*, i32*, ...)*), i64* [[DOTRELOADED]], i8*** [[ARGC_ADDR]]), !dbg [[DBG53:![0-9]+]] +// CHECK4-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB3]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64*, i8***)* @_Z5tmainIPPcEiT_..omp_par to void (i32*, i32*, ...)*), i64* [[DOTRELOADED]], i8*** [[ARGC_ADDR]]), !dbg [[DBG54:![0-9]+]] // CHECK4-NEXT: br label [[OMP_PAR_OUTLINED_EXIT:%.*]] // CHECK4: omp.par.outlined.exit: // CHECK4-NEXT: br label [[OMP_PAR_EXIT_SPLIT:%.*]] // CHECK4: omp.par.exit.split: -// CHECK4-NEXT: ret i32 0, !dbg [[DBG55:![0-9]+]] +// CHECK4-NEXT: ret i32 0, !dbg [[DBG56:![0-9]+]] // // // CHECK4-LABEL: define {{[^@]+}}@_Z5tmainIPPcEiT_..omp_par -// CHECK4-SAME: (i32* noalias [[TID_ADDR:%.*]], i32* noalias [[ZERO_ADDR:%.*]], i64* [[DOTRELOADED:%.*]], i8*** [[ARGC_ADDR:%.*]]) #[[ATTR1]] !dbg [[DBG56:![0-9]+]] { +// CHECK4-SAME: (i32* noalias [[TID_ADDR:%.*]], i32* noalias [[ZERO_ADDR:%.*]], i64* [[DOTRELOADED:%.*]], i8*** [[ARGC_ADDR:%.*]]) #[[ATTR1]] !dbg [[DBG57:![0-9]+]] { // CHECK4-NEXT: omp.par.entry: // CHECK4-NEXT: [[TID_ADDR_LOCAL:%.*]] = alloca i32, align 4 // CHECK4-NEXT: [[TMP0:%.*]] = load i32, i32* [[TID_ADDR]], align 4 @@ -936,26 +948,25 @@ // CHECK4-NEXT: [[VAR:%.*]] = alloca double*, align 8 // CHECK4-NEXT: br label [[OMP_PAR_REGION:%.*]] // CHECK4: omp.par.region: -// CHECK4-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[ARGC_ADDR]], align 8, !dbg [[DBG57:![0-9]+]] -// CHECK4-NEXT: call void @_Z3fooIPPcEvT_(i8** [[TMP2]]), !dbg [[DBG57]] -// CHECK4-NEXT: call void @llvm.dbg.declare(metadata double** [[VAR]], metadata [[META58:![0-9]+]], metadata !DIExpression()), !dbg [[DBG65:![0-9]+]] -// CHECK4-NEXT: [[TMP3:%.*]] = load double*, double** [[VAR]], align 8, !dbg [[DBG65]] -// CHECK4-NEXT: [[TMP4:%.*]] = mul nsw i64 0, [[TMP1]], !dbg [[DBG65]] -// CHECK4-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds double, double* [[TMP3]], i64 [[TMP4]], !dbg [[DBG65]] -// CHECK4-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX2]], i64 0, !dbg [[DBG65]] -// CHECK4-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]], !dbg [[DBG66:![0-9]+]] +// CHECK4-NEXT: [[TMP2:%.*]] = load i8**, i8*** [[ARGC_ADDR]], align 8, !dbg [[DBG58:![0-9]+]] +// CHECK4-NEXT: call void @_Z3fooIPPcEvT_(i8** [[TMP2]]), !dbg [[DBG58]] +// CHECK4-NEXT: call void @llvm.dbg.declare(metadata double** [[VAR]], metadata [[META59:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66:![0-9]+]] +// CHECK4-NEXT: [[TMP3:%.*]] = load double*, double** [[VAR]], align 8, !dbg [[DBG66]] +// CHECK4-NEXT: [[TMP4:%.*]] = mul nsw i64 0, [[TMP1]], !dbg [[DBG66]] +// CHECK4-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds double, double* [[TMP3]], i64 [[TMP4]], !dbg [[DBG66]] +// CHECK4-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX2]], i64 0, !dbg [[DBG66]] +// CHECK4-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]], !dbg [[DBG67:![0-9]+]] // CHECK4: omp.par.pre_finalize: -// CHECK4-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]], !dbg [[DBG66]] +// CHECK4-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]], !dbg [[DBG67]] // CHECK4: omp.par.outlined.exit.exitStub: // CHECK4-NEXT: ret void // // // CHECK4-LABEL: define {{[^@]+}}@_Z3fooIPPcEvT_ -// CHECK4-SAME: (i8** [[ARGC:%.*]]) #[[ATTR5]] comdat !dbg [[DBG67:![0-9]+]] { +// CHECK4-SAME: (i8** [[ARGC:%.*]]) #[[ATTR5]] comdat !dbg [[DBG68:![0-9]+]] { // CHECK4-NEXT: entry: // CHECK4-NEXT: [[ARGC_ADDR:%.*]] = alloca i8**, align 8 // CHECK4-NEXT: store i8** [[ARGC]], i8*** [[ARGC_ADDR]], align 8 -// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGC_ADDR]], metadata [[META70:![0-9]+]], metadata !DIExpression()), !dbg [[DBG71:![0-9]+]] -// CHECK4-NEXT: ret void, !dbg [[DBG71]] -// +// CHECK4-NEXT: call void @llvm.dbg.declare(metadata i8*** [[ARGC_ADDR]], metadata [[META71:![0-9]+]], metadata !DIExpression()), !dbg [[DBG72:![0-9]+]] +// CHECK4-NEXT: ret void, !dbg [[DBG72]] // Index: clang/test/OpenMP/parallel_for_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_for_reduction_task_codegen.cpp +++ clang/test/OpenMP/parallel_for_reduction_task_codegen.cpp @@ -452,61 +452,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -976,61 +980,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/parallel_if_codegen_PR51349.cpp =================================================================== --- clang/test/OpenMP/parallel_if_codegen_PR51349.cpp +++ clang/test/OpenMP/parallel_if_codegen_PR51349.cpp @@ -24,7 +24,7 @@ // CHECK-NEXT: call void @__kmpc_serialized_parallel(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) // CHECK-NEXT: store i32 [[TMP0]], i32* [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA3:![0-9]+]] // CHECK-NEXT: store i32 0, i32* [[DOTBOUND_ZERO_ADDR]], align 4 -// CHECK-NEXT: call void @.omp_outlined.(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTBOUND_ZERO_ADDR]]) #[[ATTR2:[0-9]+]] +// CHECK-NEXT: call void @.omp_outlined.(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTBOUND_ZERO_ADDR]]) #[[ATTR3:[0-9]+]] // CHECK-NEXT: call void @__kmpc_end_serialized_parallel(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) // CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) // CHECK-NEXT: ret void @@ -36,19 +36,23 @@ // CHECK-NEXT: entry: // CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -// CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA7:![0-9]+]] -// CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA7]] +// CHECK-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META7:![0-9]+]]) +// CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10:![0-9]+]] +// CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META12:![0-9]+]]) +// CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]] // CHECK-NEXT: ret void // // // CHECK: Function Attrs: alwaysinline norecurse nounwind // CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1 -// CHECK-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] { +// CHECK-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -// CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA7]] -// CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA7]] +// CHECK-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META14:![0-9]+]]) +// CHECK-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10]] +// CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META17:![0-9]+]]) +// CHECK-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]] // CHECK-NEXT: ret void // // @@ -62,7 +66,7 @@ // CHECK-NOINLINE-NEXT: call void @__kmpc_serialized_parallel(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) // CHECK-NOINLINE-NEXT: store i32 [[TMP0]], i32* [[DOTTHREADID_TEMP_]], align 4, !tbaa [[TBAA3:![0-9]+]] // CHECK-NOINLINE-NEXT: store i32 0, i32* [[DOTBOUND_ZERO_ADDR]], align 4 -// CHECK-NOINLINE-NEXT: call void @.omp_outlined.(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTBOUND_ZERO_ADDR]]) #[[ATTR2:[0-9]+]] +// CHECK-NOINLINE-NEXT: call void @.omp_outlined.(i32* [[DOTTHREADID_TEMP_]], i32* [[DOTBOUND_ZERO_ADDR]]) #[[ATTR3:[0-9]+]] // CHECK-NOINLINE-NEXT: call void @__kmpc_end_serialized_parallel(%struct.ident_t* @[[GLOB1]], i32 [[TMP0]]) // CHECK-NOINLINE-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*)) // CHECK-NOINLINE-NEXT: ret void @@ -74,18 +78,22 @@ // CHECK-NOINLINE-NEXT: entry: // CHECK-NOINLINE-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK-NOINLINE-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -// CHECK-NOINLINE-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA7:![0-9]+]] -// CHECK-NOINLINE-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA7]] +// CHECK-NOINLINE-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META7:![0-9]+]]) +// CHECK-NOINLINE-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10:![0-9]+]] +// CHECK-NOINLINE-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META12:![0-9]+]]) +// CHECK-NOINLINE-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]] // CHECK-NOINLINE-NEXT: ret void // // // CHECK-NOINLINE: Function Attrs: alwaysinline norecurse nounwind // CHECK-NOINLINE-LABEL: define {{[^@]+}}@.omp_outlined..1 -// CHECK-NOINLINE-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR3:[0-9]+]] { +// CHECK-NOINLINE-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]]) #[[ATTR4:[0-9]+]] { // CHECK-NOINLINE-NEXT: entry: // CHECK-NOINLINE-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK-NOINLINE-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 -// CHECK-NOINLINE-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA7]] -// CHECK-NOINLINE-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA7]] +// CHECK-NOINLINE-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META14:![0-9]+]]) +// CHECK-NOINLINE-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8, !tbaa [[TBAA10]] +// CHECK-NOINLINE-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META17:![0-9]+]]) +// CHECK-NOINLINE-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8, !tbaa [[TBAA10]] // CHECK-NOINLINE-NEXT: ret void // Index: clang/test/OpenMP/parallel_master_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_master_reduction_task_codegen.cpp +++ clang/test/OpenMP/parallel_master_reduction_task_codegen.cpp @@ -407,61 +407,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -886,61 +890,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/parallel_master_taskloop_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_codegen.cpp +++ clang/test/OpenMP/parallel_master_taskloop_codegen.cpp @@ -202,39 +202,40 @@ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META9]]), !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP24]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP25]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP26:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK1-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK1-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK1-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK1-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK1: .omp_outlined..1.exit: // CHECK1-NEXT: ret i32 0 @@ -318,39 +319,40 @@ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !28 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !28 -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !28 +// CHECK1-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK1-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META19:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META19]]), !noalias !16 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP24]], %struct.anon.0** null, i64 0, metadata [[META20]]), !noalias !16 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK1-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !16 +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: store %struct.anon.0* [[TMP25]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: [[TMP26:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !16 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK1-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !16 +// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK1-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !16 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK1-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !28 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK1-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK1-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !28 +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !16 +// CHECK1-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !16 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !16 +// CHECK1-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK1-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !16 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK1: .omp_outlined..3.exit: // CHECK1-NEXT: ret i32 0 @@ -498,115 +500,116 @@ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META29:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META32:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META34:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !40 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !40 -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP22:%.*]] = load i32*, i32** [[TMP21]], align 8 -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[TMP22]], align 4 -// CHECK1-NEXT: store i32 [[TMP23]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32*, i32** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP25]], align 4 -// CHECK1-NEXT: store i32 [[TMP26]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP28:%.*]] = load i8***, i8**** [[TMP27]], align 8 -// CHECK1-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[TMP28]], align 8 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP31]], align 4 -// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP32]] to i64 -// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP29]], i64 [[IDXPROM_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8 -// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8 -// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4 -// CHECK1-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP36]] to i64 -// CHECK1-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP33]], i64 [[IDXPROM4_I]] -// CHECK1-NEXT: [[TMP37:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1 -// CHECK1-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP37]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 -// CHECK1-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP38]] to i64 -// CHECK1-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP39]], [[TMP40]] +// CHECK1-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK1-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META21]]), !noalias !24 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META27]]), !noalias !24 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP24]], %struct.anon.2** null, i64 0, metadata [[META28]]), !noalias !24 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK1-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !24 +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store %struct.anon.2* [[TMP25]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP26:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32*, i32** [[TMP27]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4, !noalias !24 +// CHECK1-NEXT: store i32 [[TMP29]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !24 +// CHECK1-NEXT: store i32 [[TMP32]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP34:%.*]] = load i8***, i8**** [[TMP33]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP35:%.*]] = load i8**, i8*** [[TMP34]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP37]], align 4, !noalias !24 +// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP38]] to i64 +// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP35]], i64 [[IDXPROM_I]] +// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP42:%.*]] = load i32, i32* [[TMP41]], align 4, !noalias !24 +// CHECK1-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP42]] to i64 +// CHECK1-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP39]], i64 [[IDXPROM4_I]] +// CHECK1-NEXT: [[TMP43:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1, !noalias !24 +// CHECK1-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP43]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !24 +// CHECK1-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP44]] to i64 +// CHECK1-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP45]], [[TMP46]] // CHECK1-NEXT: [[SUB9_I:%.*]] = sub i32 [[SUB8_I]], 1 // CHECK1-NEXT: [[CONV11_I:%.*]] = zext i32 [[SUB8_I]] to i64 // CHECK1-NEXT: [[MUL_I:%.*]] = mul nsw i64 [[CONV7_I]], [[CONV11_I]] // CHECK1-NEXT: [[SUB12_I:%.*]] = sub nsw i64 [[MUL_I]], 1 -// CHECK1-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !40 -// CHECK1-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK1-NEXT: store i32 [[TMP41]], i32* [[J_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP42]] +// CHECK1-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK1-NEXT: store i32 [[TMP47]], i32* [[J_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !24 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP48]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[LAND_LHS_TRUE_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] // CHECK1: land.lhs.true.i: -// CHECK1-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP43]], [[TMP44]] +// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP49]], [[TMP50]] // CHECK1-NEXT: br i1 [[CMP13_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT]] // CHECK1: taskloop.if.then.i: -// CHECK1-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: store i64 [[TMP45]], i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP47:%.*]] = load i32*, i32** [[TMP46]], align 8 -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP49:%.*]] = load i8***, i8**** [[TMP48]], align 8 +// CHECK1-NEXT: [[TMP51:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i64 [[TMP51]], i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP53:%.*]] = load i32*, i32** [[TMP52]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP55:%.*]] = load i8***, i8**** [[TMP54]], align 8, !noalias !24 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP50:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK1-NEXT: [[TMP51:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !40 -// CHECK1-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP50]], [[TMP51]] +// CHECK1-NEXT: [[TMP56:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP56]], [[TMP57]] // CHECK1-NEXT: br i1 [[CMP16_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP52:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK1-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP53]], [[TMP54]] +// CHECK1-NEXT: [[TMP58:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP59]], [[TMP60]] // CHECK1-NEXT: [[SUB18_I:%.*]] = sub i32 [[SUB17_I]], 1 // CHECK1-NEXT: [[CONV22_I:%.*]] = zext i32 [[SUB17_I]] to i64 -// CHECK1-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP52]], [[CONV22_I]] +// CHECK1-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP58]], [[CONV22_I]] // CHECK1-NEXT: [[CONV26_I:%.*]] = trunc i64 [[DIV23_I]] to i32 -// CHECK1-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP55]] to i64 -// CHECK1-NEXT: [[TMP56:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK1-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP58]], [[TMP59]] +// CHECK1-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP61]] to i64 +// CHECK1-NEXT: [[TMP62:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP63:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP64:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP65:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP64]], [[TMP65]] // CHECK1-NEXT: [[SUB29_I:%.*]] = sub i32 [[SUB28_I]], 1 // CHECK1-NEXT: [[CONV33_I:%.*]] = zext i32 [[SUB28_I]] to i64 -// CHECK1-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP57]], [[CONV33_I]] -// CHECK1-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP60]], [[TMP61]] +// CHECK1-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP63]], [[CONV33_I]] +// CHECK1-NEXT: [[TMP66:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP67:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP66]], [[TMP67]] // CHECK1-NEXT: [[SUB36_I:%.*]] = sub i32 [[SUB35_I]], 1 // CHECK1-NEXT: [[CONV40_I:%.*]] = zext i32 [[SUB35_I]] to i64 // CHECK1-NEXT: [[MUL41_I:%.*]] = mul nsw i64 [[DIV34_I]], [[CONV40_I]] -// CHECK1-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP56]], [[MUL41_I]] +// CHECK1-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP62]], [[MUL41_I]] // CHECK1-NEXT: [[ADD44_I:%.*]] = add nsw i64 [[CONV27_I]], [[SUB42_I]] // CHECK1-NEXT: [[CONV45_I:%.*]] = trunc i64 [[ADD44_I]] to i32 -// CHECK1-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !40 -// CHECK1-NEXT: [[TMP62:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK1-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP62]], 1 -// CHECK1-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !40 +// CHECK1-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP68:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP68]], 1 +// CHECK1-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !24 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK1: omp.inner.for.end.i: // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__6_EXIT]] @@ -690,61 +693,62 @@ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META41:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META44:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META46:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !52 -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !52 +// CHECK1-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META29:![0-9]+]]) +// CHECK1-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META29]]), !noalias !32 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META35:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META35]]), !noalias !32 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META36:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP24]], %struct.anon.4** null, i64 0, metadata [[META36]]), !noalias !32 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK1-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !32 +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store %struct.anon.4* [[TMP25]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: [[TMP26:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !32 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !52 -// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK1-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32 +// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK1-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !52 -// CHECK1-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !52 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK1-NEXT: [[TMP26:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP25]], i32 4) #[[ATTR2]] -// CHECK1-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK1-NEXT: br i1 [[TMP27]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32 +// CHECK1-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !32 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK1-NEXT: [[TMP32:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP31]], i32 4) #[[ATTR2]], !noalias !32 +// CHECK1-NEXT: [[TMP33:%.*]] = icmp ne i32 [[TMP32]], 0 +// CHECK1-NEXT: br i1 [[TMP33]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK1: .cancel.exit.i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK1: .cancel.continue.i: -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK1-NEXT: [[TMP29:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP28]], i32 4) #[[ATTR2]] -// CHECK1-NEXT: [[TMP30:%.*]] = icmp ne i32 [[TMP29]], 0 -// CHECK1-NEXT: br i1 [[TMP30]], label [[DOTCANCEL_EXIT2_I:%.*]], label [[DOTCANCEL_CONTINUE3_I:%.*]] +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK1-NEXT: [[TMP35:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP34]], i32 4) #[[ATTR2]], !noalias !32 +// CHECK1-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK1-NEXT: br i1 [[TMP36]], label [[DOTCANCEL_EXIT2_I:%.*]], label [[DOTCANCEL_CONTINUE3_I:%.*]] // CHECK1: .cancel.exit2.i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT]] // CHECK1: .cancel.continue3.i: -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !52 -// CHECK1-NEXT: [[ADD4_I:%.*]] = add nsw i32 [[TMP31]], 1 -// CHECK1-NEXT: store i32 [[ADD4_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !52 +// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32 +// CHECK1-NEXT: [[ADD4_I:%.*]] = add nsw i32 [[TMP37]], 1 +// CHECK1-NEXT: store i32 [[ADD4_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !32 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK1: omp.inner.for.end.i: -// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT]] // CHECK1: .omp_outlined..9.exit: -// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 // CHECK1-NEXT: ret i32 0 // // @@ -908,60 +912,61 @@ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META53:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META62:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !64 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !64 -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON_6:%.*]], %struct.anon.6* [[TMP20]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.S*, %struct.S** [[TMP21]], align 8 -// CHECK1-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !64 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON_6]], %struct.anon.6* [[TMP20]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = load i32*, i32** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK1-NEXT: store i32 [[TMP25]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK1-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP26]], 1 -// CHECK1-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !64 -// CHECK1-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !64 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i32 0, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP28]] +// CHECK1-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META37:![0-9]+]]) +// CHECK1-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META37]]), !noalias !40 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META43:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META43]]), !noalias !40 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META44:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP24]], %struct.anon.6** null, i64 0, metadata [[META44]]), !noalias !40 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !40 +// CHECK1-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !40 +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: store %struct.anon.6* [[TMP25]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: [[TMP26:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_6:%.*]], %struct.anon.6* [[TMP26]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP28:%.*]] = load %struct.S*, %struct.S** [[TMP27]], align 8, !noalias !40 +// CHECK1-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !40 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_6]], %struct.anon.6* [[TMP26]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8, !noalias !40 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4, !noalias !40 +// CHECK1-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 +// CHECK1-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP32]], 1 +// CHECK1-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 +// CHECK1-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !40 +// CHECK1-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !40 +// CHECK1-NEXT: store i32 0, i32* [[TMP33]], align 4, !noalias !40 +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP34]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[DOTOMP_OUTLINED__12_EXIT:%.*]] // CHECK1: taskloop.if.then.i: -// CHECK1-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !64 -// CHECK1-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP29]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_6]], %struct.anon.6* [[TMP20]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 +// CHECK1-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !40 +// CHECK1-NEXT: [[TMP35:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP35]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !40 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_6]], %struct.anon.6* [[TMP26]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !40 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK1-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP32]] to i64 -// CHECK1-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP33]] +// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !40 +// CHECK1-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP38]] to i64 +// CHECK1-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !40 +// CHECK1-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP39]] // CHECK1-NEXT: br i1 [[CMP8_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i32 [[TMP34]], i32* [[TMP35]], align 4 -// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK1-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP36]], 1 -// CHECK1-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !64 +// CHECK1-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !40 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !40 +// CHECK1-NEXT: store i32 [[TMP40]], i32* [[TMP41]], align 4, !noalias !40 +// CHECK1-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !40 +// CHECK1-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP42]], 1 +// CHECK1-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !40 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK1: omp.inner.for.end.i: // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__12_EXIT]] @@ -1128,39 +1133,40 @@ // CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META9]]), !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP24]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP25]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP26:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK2-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK2-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK2-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK2-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK2: .omp_outlined..1.exit: // CHECK2-NEXT: ret i32 0 @@ -1244,39 +1250,40 @@ // CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !28 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !28 -// CHECK2-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !28 +// CHECK2-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK2-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META19:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META19]]), !noalias !16 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP24]], %struct.anon.0** null, i64 0, metadata [[META20]]), !noalias !16 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK2-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !16 +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: store %struct.anon.0* [[TMP25]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: [[TMP26:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !16 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK2-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !16 +// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK2-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !16 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK2-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !28 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK2-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK2-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !28 +// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !16 +// CHECK2-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !16 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !16 +// CHECK2-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK2-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !16 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK2: .omp_outlined..3.exit: // CHECK2-NEXT: ret i32 0 @@ -1424,115 +1431,116 @@ // CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META29:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META32:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META34:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !40 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !40 -// CHECK2-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP22:%.*]] = load i32*, i32** [[TMP21]], align 8 -// CHECK2-NEXT: [[TMP23:%.*]] = load i32, i32* [[TMP22]], align 4 -// CHECK2-NEXT: store i32 [[TMP23]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32*, i32** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP25]], align 4 -// CHECK2-NEXT: store i32 [[TMP26]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP28:%.*]] = load i8***, i8**** [[TMP27]], align 8 -// CHECK2-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[TMP28]], align 8 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP31]], align 4 -// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP32]] to i64 -// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP29]], i64 [[IDXPROM_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8 -// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8 -// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4 -// CHECK2-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP36]] to i64 -// CHECK2-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP33]], i64 [[IDXPROM4_I]] -// CHECK2-NEXT: [[TMP37:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1 -// CHECK2-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP37]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 -// CHECK2-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP38]] to i64 -// CHECK2-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP39]], [[TMP40]] +// CHECK2-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK2-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META21]]), !noalias !24 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META27]]), !noalias !24 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP24]], %struct.anon.2** null, i64 0, metadata [[META28]]), !noalias !24 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK2-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !24 +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store %struct.anon.2* [[TMP25]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP26:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32*, i32** [[TMP27]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4, !noalias !24 +// CHECK2-NEXT: store i32 [[TMP29]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !24 +// CHECK2-NEXT: store i32 [[TMP32]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP34:%.*]] = load i8***, i8**** [[TMP33]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP35:%.*]] = load i8**, i8*** [[TMP34]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP37]], align 4, !noalias !24 +// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP38]] to i64 +// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP35]], i64 [[IDXPROM_I]] +// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP42:%.*]] = load i32, i32* [[TMP41]], align 4, !noalias !24 +// CHECK2-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP42]] to i64 +// CHECK2-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP39]], i64 [[IDXPROM4_I]] +// CHECK2-NEXT: [[TMP43:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1, !noalias !24 +// CHECK2-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP43]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !24 +// CHECK2-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP44]] to i64 +// CHECK2-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP45]], [[TMP46]] // CHECK2-NEXT: [[SUB9_I:%.*]] = sub i32 [[SUB8_I]], 1 // CHECK2-NEXT: [[CONV11_I:%.*]] = zext i32 [[SUB8_I]] to i64 // CHECK2-NEXT: [[MUL_I:%.*]] = mul nsw i64 [[CONV7_I]], [[CONV11_I]] // CHECK2-NEXT: [[SUB12_I:%.*]] = sub nsw i64 [[MUL_I]], 1 -// CHECK2-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !40 -// CHECK2-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK2-NEXT: store i32 [[TMP41]], i32* [[J_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP42]] +// CHECK2-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK2-NEXT: store i32 [[TMP47]], i32* [[J_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !24 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP48]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[LAND_LHS_TRUE_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] // CHECK2: land.lhs.true.i: -// CHECK2-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP43]], [[TMP44]] +// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP49]], [[TMP50]] // CHECK2-NEXT: br i1 [[CMP13_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT]] // CHECK2: taskloop.if.then.i: -// CHECK2-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: store i64 [[TMP45]], i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP47:%.*]] = load i32*, i32** [[TMP46]], align 8 -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP20]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP49:%.*]] = load i8***, i8**** [[TMP48]], align 8 +// CHECK2-NEXT: [[TMP51:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i64 [[TMP51]], i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP53:%.*]] = load i32*, i32** [[TMP52]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP26]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP55:%.*]] = load i8***, i8**** [[TMP54]], align 8, !noalias !24 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP50:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK2-NEXT: [[TMP51:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !40 -// CHECK2-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP50]], [[TMP51]] +// CHECK2-NEXT: [[TMP56:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP56]], [[TMP57]] // CHECK2-NEXT: br i1 [[CMP16_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP52:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK2-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP53]], [[TMP54]] +// CHECK2-NEXT: [[TMP58:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP59]], [[TMP60]] // CHECK2-NEXT: [[SUB18_I:%.*]] = sub i32 [[SUB17_I]], 1 // CHECK2-NEXT: [[CONV22_I:%.*]] = zext i32 [[SUB17_I]] to i64 -// CHECK2-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP52]], [[CONV22_I]] +// CHECK2-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP58]], [[CONV22_I]] // CHECK2-NEXT: [[CONV26_I:%.*]] = trunc i64 [[DIV23_I]] to i32 -// CHECK2-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP55]] to i64 -// CHECK2-NEXT: [[TMP56:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK2-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP58]], [[TMP59]] +// CHECK2-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP61]] to i64 +// CHECK2-NEXT: [[TMP62:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP63:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP64:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP65:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP64]], [[TMP65]] // CHECK2-NEXT: [[SUB29_I:%.*]] = sub i32 [[SUB28_I]], 1 // CHECK2-NEXT: [[CONV33_I:%.*]] = zext i32 [[SUB28_I]] to i64 -// CHECK2-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP57]], [[CONV33_I]] -// CHECK2-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP60]], [[TMP61]] +// CHECK2-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP63]], [[CONV33_I]] +// CHECK2-NEXT: [[TMP66:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP67:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP66]], [[TMP67]] // CHECK2-NEXT: [[SUB36_I:%.*]] = sub i32 [[SUB35_I]], 1 // CHECK2-NEXT: [[CONV40_I:%.*]] = zext i32 [[SUB35_I]] to i64 // CHECK2-NEXT: [[MUL41_I:%.*]] = mul nsw i64 [[DIV34_I]], [[CONV40_I]] -// CHECK2-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP56]], [[MUL41_I]] +// CHECK2-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP62]], [[MUL41_I]] // CHECK2-NEXT: [[ADD44_I:%.*]] = add nsw i64 [[CONV27_I]], [[SUB42_I]] // CHECK2-NEXT: [[CONV45_I:%.*]] = trunc i64 [[ADD44_I]] to i32 -// CHECK2-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !40 -// CHECK2-NEXT: [[TMP62:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !40 -// CHECK2-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP62]], 1 -// CHECK2-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !40 +// CHECK2-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP68:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP68]], 1 +// CHECK2-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !24 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK2: omp.inner.for.end.i: // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__6_EXIT]] @@ -1616,61 +1624,62 @@ // CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META41:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META44:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META46:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !52 -// CHECK2-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !52 +// CHECK2-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META29:![0-9]+]]) +// CHECK2-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META29]]), !noalias !32 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META35:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META35]]), !noalias !32 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META36:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP24]], %struct.anon.4** null, i64 0, metadata [[META36]]), !noalias !32 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK2-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !32 +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store %struct.anon.4* [[TMP25]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: [[TMP26:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !32 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !52 -// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK2-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32 +// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK2-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !52 -// CHECK2-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !52 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK2-NEXT: [[TMP26:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP25]], i32 4) #[[ATTR2]] -// CHECK2-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK2-NEXT: br i1 [[TMP27]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] +// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32 +// CHECK2-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !32 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK2-NEXT: [[TMP32:%.*]] = call i32 @__kmpc_cancel(%struct.ident_t* @[[GLOB1]], i32 [[TMP31]], i32 4) #[[ATTR2]], !noalias !32 +// CHECK2-NEXT: [[TMP33:%.*]] = icmp ne i32 [[TMP32]], 0 +// CHECK2-NEXT: br i1 [[TMP33]], label [[DOTCANCEL_EXIT_I:%.*]], label [[DOTCANCEL_CONTINUE_I:%.*]] // CHECK2: .cancel.exit.i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK2: .cancel.continue.i: -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK2-NEXT: [[TMP29:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP28]], i32 4) #[[ATTR2]] -// CHECK2-NEXT: [[TMP30:%.*]] = icmp ne i32 [[TMP29]], 0 -// CHECK2-NEXT: br i1 [[TMP30]], label [[DOTCANCEL_EXIT2_I:%.*]], label [[DOTCANCEL_CONTINUE3_I:%.*]] +// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK2-NEXT: [[TMP35:%.*]] = call i32 @__kmpc_cancellationpoint(%struct.ident_t* @[[GLOB1]], i32 [[TMP34]], i32 4) #[[ATTR2]], !noalias !32 +// CHECK2-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK2-NEXT: br i1 [[TMP36]], label [[DOTCANCEL_EXIT2_I:%.*]], label [[DOTCANCEL_CONTINUE3_I:%.*]] // CHECK2: .cancel.exit2.i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT]] // CHECK2: .cancel.continue3.i: -// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !52 -// CHECK2-NEXT: [[ADD4_I:%.*]] = add nsw i32 [[TMP31]], 1 -// CHECK2-NEXT: store i32 [[ADD4_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !52 +// CHECK2-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32 +// CHECK2-NEXT: [[ADD4_I:%.*]] = add nsw i32 [[TMP37]], 1 +// CHECK2-NEXT: store i32 [[ADD4_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !32 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK2: omp.inner.for.end.i: -// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT]] // CHECK2: .omp_outlined..9.exit: -// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 // CHECK2-NEXT: ret i32 0 // // @@ -1834,60 +1843,61 @@ // CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META53:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META62:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !64 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !64 -// CHECK2-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON_6:%.*]], %struct.anon.6* [[TMP20]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.S*, %struct.S** [[TMP21]], align 8 -// CHECK2-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !64 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON_6]], %struct.anon.6* [[TMP20]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = load i32*, i32** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK2-NEXT: store i32 [[TMP25]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK2-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK2-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP26]], 1 -// CHECK2-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !64 -// CHECK2-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !64 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i32 0, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP28]] +// CHECK2-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META37:![0-9]+]]) +// CHECK2-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META37]]), !noalias !40 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META43:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META43]]), !noalias !40 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META44:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP24]], %struct.anon.6** null, i64 0, metadata [[META44]]), !noalias !40 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !40 +// CHECK2-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !40 +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: store %struct.anon.6* [[TMP25]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: [[TMP26:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_6:%.*]], %struct.anon.6* [[TMP26]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP28:%.*]] = load %struct.S*, %struct.S** [[TMP27]], align 8, !noalias !40 +// CHECK2-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !40 +// CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_6]], %struct.anon.6* [[TMP26]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8, !noalias !40 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4, !noalias !40 +// CHECK2-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 +// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 +// CHECK2-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP32]], 1 +// CHECK2-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !40 +// CHECK2-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !40 +// CHECK2-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !40 +// CHECK2-NEXT: store i32 0, i32* [[TMP33]], align 4, !noalias !40 +// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !40 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP34]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[DOTOMP_OUTLINED__12_EXIT:%.*]] // CHECK2: taskloop.if.then.i: -// CHECK2-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !64 -// CHECK2-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP29]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_6]], %struct.anon.6* [[TMP20]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 +// CHECK2-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !40 +// CHECK2-NEXT: [[TMP35:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP35]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !40 +// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_6]], %struct.anon.6* [[TMP26]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !40 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK2-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP32]] to i64 -// CHECK2-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP33]] +// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !40 +// CHECK2-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP38]] to i64 +// CHECK2-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !40 +// CHECK2-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP39]] // CHECK2-NEXT: br i1 [[CMP8_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i32 [[TMP34]], i32* [[TMP35]], align 4 -// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK2-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP36]], 1 -// CHECK2-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !64 +// CHECK2-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !40 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !40 +// CHECK2-NEXT: store i32 [[TMP40]], i32* [[TMP41]], align 4, !noalias !40 +// CHECK2-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !40 +// CHECK2-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP42]], 1 +// CHECK2-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !40 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK2: omp.inner.for.end.i: // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__12_EXIT]] Index: clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp +++ clang/test/OpenMP/parallel_master_taskloop_firstprivate_codegen.cpp @@ -284,7 +284,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -424,7 +425,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp +++ clang/test/OpenMP/parallel_master_taskloop_lastprivate_codegen.cpp @@ -420,101 +420,106 @@ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* -// CHECK1-NEXT: call void [[TMP25]](i8* [[TMP24]], %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], i32** [[DOTLASTPRIV_PTR_ADDR4_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 3 -// CHECK1-NEXT: [[TMP27:%.*]] = load %struct.S*, %struct.S** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP30]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP33:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP32]], align 8 -// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP35:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP34]], align 8 -// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 3 -// CHECK1-NEXT: [[TMP37:%.*]] = load %struct.S*, %struct.S** [[TMP36]], align 8 -// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 4 -// CHECK1-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = load %struct.S*, %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP42:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP43:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP44:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR4_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK1-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK1-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* +// CHECK1-NEXT: call void [[TMP35]](i8* [[TMP34]], %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], i32** [[DOTLASTPRIV_PTR_ADDR4_I]]) #[[ATTR4]], !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 3 +// CHECK1-NEXT: [[TMP37:%.*]] = load %struct.S*, %struct.S** [[TMP36]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP41:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP40]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP43:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP42]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP45:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP44]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 3 +// CHECK1-NEXT: [[TMP47:%.*]] = load %struct.S*, %struct.S** [[TMP46]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 4 +// CHECK1-NEXT: [[TMP49:%.*]] = load i32*, i32** [[TMP48]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP50:%.*]] = load %struct.S*, %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP53:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP54:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR4_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK1-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV5_I]], [[TMP47]] +// CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK1-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV5_I]], [[TMP57]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[TMP41]], align 4 -// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP43]], i64 0, i64 0 -// CHECK1-NEXT: store i32 [[TMP49]], i32* [[ARRAYIDX_I]], align 4 -// CHECK1-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP42]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP50:%.*]] = bitcast %struct.S* [[ARRAYIDX6_I]] to i8* -// CHECK1-NEXT: [[TMP51:%.*]] = bitcast %struct.S* [[TMP40]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP50]], i8* align 8 [[TMP51]], i64 8, i1 false) #[[ATTR4]] -// CHECK1-NEXT: store i32 33, i32* [[TMP44]], align 4 -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[TMP51]], align 4, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP53]], i64 0, i64 0 +// CHECK1-NEXT: store i32 [[TMP59]], i32* [[ARRAYIDX_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP52]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP60:%.*]] = bitcast %struct.S* [[ARRAYIDX6_I]] to i8* +// CHECK1-NEXT: [[TMP61:%.*]] = bitcast %struct.S* [[TMP50]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP60]], i8* align 8 [[TMP61]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK1-NEXT: store i32 33, i32* [[TMP54]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK1: omp.inner.for.end.i: -// CHECK1-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP54:%.*]] = icmp ne i32 [[TMP53]], 0 -// CHECK1-NEXT: br i1 [[TMP54]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK1-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP64:%.*]] = icmp ne i32 [[TMP63]], 0 +// CHECK1-NEXT: br i1 [[TMP64]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: .omp.lastprivate.then.i: -// CHECK1-NEXT: [[TMP55:%.*]] = bitcast %struct.S* [[TMP27]] to i8* -// CHECK1-NEXT: [[TMP56:%.*]] = bitcast %struct.S* [[TMP40]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP55]], i8* align 8 [[TMP56]], i64 8, i1 false) #[[ATTR4]] -// CHECK1-NEXT: [[TMP57:%.*]] = load i32, i32* [[TMP41]], align 4 -// CHECK1-NEXT: store i32 [[TMP57]], i32* [[TMP29]], align 4 -// CHECK1-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP31]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP58:%.*]] = bitcast [2 x %struct.S]* [[TMP42]] to %struct.S* -// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[ARRAY_BEGIN_I]], i64 2 +// CHECK1-NEXT: [[TMP65:%.*]] = bitcast %struct.S* [[TMP37]] to i8* +// CHECK1-NEXT: [[TMP66:%.*]] = bitcast %struct.S* [[TMP50]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP65]], i8* align 8 [[TMP66]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK1-NEXT: [[TMP67:%.*]] = load i32, i32* [[TMP51]], align 4, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP67]], i32* [[TMP39]], align 4, !noalias !6 +// CHECK1-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP41]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP68:%.*]] = bitcast [2 x %struct.S]* [[TMP52]] to %struct.S* +// CHECK1-NEXT: [[TMP69:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[ARRAY_BEGIN_I]], i64 2 // CHECK1-NEXT: br label [[OMP_ARRAYCPY_BODY_I:%.*]] // CHECK1: omp.arraycpy.body.i: -// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S* [ [[TMP58]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] +// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S* [ [[TMP68]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST_I:%.*]] = phi %struct.S* [ [[ARRAY_BEGIN_I]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] -// CHECK1-NEXT: [[TMP60:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* -// CHECK1-NEXT: [[TMP61:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP60]], i8* align 8 [[TMP61]], i64 8, i1 false) #[[ATTR4]] +// CHECK1-NEXT: [[TMP70:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* +// CHECK1-NEXT: [[TMP71:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP70]], i8* align 8 [[TMP71]], i64 8, i1 false) #[[ATTR4]], !noalias !6 // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT_I]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]], i32 1 // CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT_I]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]], i32 1 -// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP59]] +// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP69]] // CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE_I]], label [[OMP_ARRAYCPY_DONE8_I:%.*]], label [[OMP_ARRAYCPY_BODY_I]] // CHECK1: omp.arraycpy.done8.i: -// CHECK1-NEXT: [[TMP62:%.*]] = bitcast [2 x i32]* [[TMP33]] to i8* -// CHECK1-NEXT: [[TMP63:%.*]] = bitcast [2 x i32]* [[TMP43]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP62]], i8* align 4 [[TMP63]], i64 8, i1 false) #[[ATTR4]] -// CHECK1-NEXT: [[TMP64:%.*]] = load i32, i32* [[TMP44]], align 4 -// CHECK1-NEXT: store i32 [[TMP64]], i32* [[TMP39]], align 4 +// CHECK1-NEXT: [[TMP72:%.*]] = bitcast [2 x i32]* [[TMP43]] to i8* +// CHECK1-NEXT: [[TMP73:%.*]] = bitcast [2 x i32]* [[TMP53]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP72]], i8* align 4 [[TMP73]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK1-NEXT: [[TMP74:%.*]] = load i32, i32* [[TMP54]], align 4, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP74]], i32* [[TMP49]], align 4, !noalias !6 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .omp_outlined..1.exit: // CHECK1-NEXT: ret i32 0 @@ -835,95 +840,100 @@ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 64 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !28 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.3*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* @.omp_task_privates_map..4 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !28 -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: store %struct.anon.1* [[TMP8]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* -// CHECK1-NEXT: call void [[TMP25]](i8* [[TMP24]], i32** [[DOTLASTPRIV_PTR_ADDR_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP29:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP28]], align 8 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP30]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP33:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP32]], align 8 -// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 3 -// CHECK1-NEXT: [[TMP35:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP34]], align 8 -// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 3 -// CHECK1-NEXT: [[TMP37:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP36]], align 8 -// CHECK1-NEXT: [[TMP38:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP39:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP40:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP41:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP42]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !28 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META25]]), !noalias !20 +// CHECK1-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK1-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.3*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* @.omp_task_privates_map..4 to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META26]]), !noalias !20 +// CHECK1-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK1-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META27]]), !noalias !20 +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK1-NEXT: [[TMP31:%.*]] = call %struct.anon.1* @llvm.noalias.p0s_struct.anon.1s.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1* [[TMP8]], i8* [[TMP30]], %struct.anon.1** null, i64 0, metadata [[META28]]), !noalias !20 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK1-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !20 +// CHECK1-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store %struct.anon.1* [[TMP31]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP32:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* +// CHECK1-NEXT: call void [[TMP35]](i8* [[TMP34]], i32** [[DOTLASTPRIV_PTR_ADDR_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !20 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP39:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP38]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP41:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP40]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP43:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP42]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 3 +// CHECK1-NEXT: [[TMP45:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP44]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 3 +// CHECK1-NEXT: [[TMP47:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP46]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP48:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP49:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP50:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP51:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP52:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP52]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !20 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !28 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP44]] +// CHECK1-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !20 +// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP53]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP54]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK1-NEXT: store i32 [[TMP45]], i32* [[I_I]], align 4, !noalias !28 -// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[TMP38]], align 128 -// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP39]], i64 0, i64 0 -// CHECK1-NEXT: store i32 [[TMP46]], i32* [[ARRAYIDX_I]], align 4 -// CHECK1-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP40]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP47:%.*]] = bitcast %struct.S.0* [[ARRAYIDX5_I]] to i8* -// CHECK1-NEXT: [[TMP48:%.*]] = bitcast %struct.S.0* [[TMP41]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP47]], i8* align 4 [[TMP48]], i64 4, i1 false) #[[ATTR4]] -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP49]], 1 -// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !28 +// CHECK1-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !20 +// CHECK1-NEXT: store i32 [[TMP55]], i32* [[I_I]], align 4, !noalias !20 +// CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP48]], align 128, !noalias !20 +// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP49]], i64 0, i64 0 +// CHECK1-NEXT: store i32 [[TMP56]], i32* [[ARRAYIDX_I]], align 4, !noalias !20 +// CHECK1-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP50]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP57:%.*]] = bitcast %struct.S.0* [[ARRAYIDX5_I]] to i8* +// CHECK1-NEXT: [[TMP58:%.*]] = bitcast %struct.S.0* [[TMP51]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP57]], i8* align 4 [[TMP58]], i64 4, i1 false) #[[ATTR4]], !noalias !20 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !20 +// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP59]], 1 +// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !20 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK1: omp.inner.for.end.i: -// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !28 -// CHECK1-NEXT: [[TMP51:%.*]] = icmp ne i32 [[TMP50]], 0 -// CHECK1-NEXT: br i1 [[TMP51]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK1-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !20 +// CHECK1-NEXT: [[TMP61:%.*]] = icmp ne i32 [[TMP60]], 0 +// CHECK1-NEXT: br i1 [[TMP61]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK1: .omp.lastprivate.then.i: -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[TMP38]], align 128 -// CHECK1-NEXT: store i32 [[TMP52]], i32* [[TMP27]], align 128 -// CHECK1-NEXT: [[TMP53:%.*]] = bitcast [2 x i32]* [[TMP29]] to i8* -// CHECK1-NEXT: [[TMP54:%.*]] = bitcast [2 x i32]* [[TMP39]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP53]], i8* align 4 [[TMP54]], i64 8, i1 false) #[[ATTR4]] -// CHECK1-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP31]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP55:%.*]] = bitcast [2 x %struct.S.0]* [[TMP40]] to %struct.S.0* -// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN_I]], i64 2 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[TMP48]], align 128, !noalias !20 +// CHECK1-NEXT: store i32 [[TMP62]], i32* [[TMP37]], align 128, !noalias !20 +// CHECK1-NEXT: [[TMP63:%.*]] = bitcast [2 x i32]* [[TMP39]] to i8* +// CHECK1-NEXT: [[TMP64:%.*]] = bitcast [2 x i32]* [[TMP49]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP63]], i8* align 4 [[TMP64]], i64 8, i1 false) #[[ATTR4]], !noalias !20 +// CHECK1-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP41]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP65:%.*]] = bitcast [2 x %struct.S.0]* [[TMP50]] to %struct.S.0* +// CHECK1-NEXT: [[TMP66:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN_I]], i64 2 // CHECK1-NEXT: br label [[OMP_ARRAYCPY_BODY_I:%.*]] // CHECK1: omp.arraycpy.body.i: -// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[TMP55]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] +// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[TMP65]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN_I]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] -// CHECK1-NEXT: [[TMP57:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* -// CHECK1-NEXT: [[TMP58:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP57]], i8* align 4 [[TMP58]], i64 4, i1 false) #[[ATTR4]] +// CHECK1-NEXT: [[TMP67:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* +// CHECK1-NEXT: [[TMP68:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP67]], i8* align 4 [[TMP68]], i64 4, i1 false) #[[ATTR4]], !noalias !20 // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT_I]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]], i32 1 // CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT_I]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]], i32 1 -// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP56]] +// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP66]] // CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE_I]], label [[OMP_ARRAYCPY_DONE7_I:%.*]], label [[OMP_ARRAYCPY_BODY_I]] // CHECK1: omp.arraycpy.done7.i: -// CHECK1-NEXT: [[TMP59:%.*]] = bitcast %struct.S.0* [[TMP35]] to i8* -// CHECK1-NEXT: [[TMP60:%.*]] = bitcast %struct.S.0* [[TMP41]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP59]], i8* align 4 [[TMP60]], i64 4, i1 false) #[[ATTR4]] +// CHECK1-NEXT: [[TMP69:%.*]] = bitcast %struct.S.0* [[TMP45]] to i8* +// CHECK1-NEXT: [[TMP70:%.*]] = bitcast %struct.S.0* [[TMP51]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP69]], i8* align 4 [[TMP70]], i64 4, i1 false) #[[ATTR4]], !noalias !20 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK1: .omp_outlined..3.exit: // CHECK1-NEXT: ret i32 0 @@ -1254,101 +1264,106 @@ // CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* -// CHECK2-NEXT: call void [[TMP25]](i8* [[TMP24]], %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], i32** [[DOTLASTPRIV_PTR_ADDR4_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 3 -// CHECK2-NEXT: [[TMP27:%.*]] = load %struct.S*, %struct.S** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP30]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP33:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP32]], align 8 -// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP35:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP34]], align 8 -// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 3 -// CHECK2-NEXT: [[TMP37:%.*]] = load %struct.S*, %struct.S** [[TMP36]], align 8 -// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 4 -// CHECK2-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = load %struct.S*, %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP42:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP43:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP44:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR4_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK2-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK2-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* +// CHECK2-NEXT: call void [[TMP35]](i8* [[TMP34]], %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], i32** [[DOTLASTPRIV_PTR_ADDR4_I]]) #[[ATTR4]], !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 3 +// CHECK2-NEXT: [[TMP37:%.*]] = load %struct.S*, %struct.S** [[TMP36]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP41:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP40]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP43:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP42]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP45:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP44]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 3 +// CHECK2-NEXT: [[TMP47:%.*]] = load %struct.S*, %struct.S** [[TMP46]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 4 +// CHECK2-NEXT: [[TMP49:%.*]] = load i32*, i32** [[TMP48]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP50:%.*]] = load %struct.S*, %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP53:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP54:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR4_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK2-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV5_I]], [[TMP47]] +// CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK2-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV5_I]], [[TMP57]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[TMP41]], align 4 -// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP43]], i64 0, i64 0 -// CHECK2-NEXT: store i32 [[TMP49]], i32* [[ARRAYIDX_I]], align 4 -// CHECK2-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP42]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP50:%.*]] = bitcast %struct.S* [[ARRAYIDX6_I]] to i8* -// CHECK2-NEXT: [[TMP51:%.*]] = bitcast %struct.S* [[TMP40]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP50]], i8* align 8 [[TMP51]], i64 8, i1 false) #[[ATTR4]] -// CHECK2-NEXT: store i32 33, i32* [[TMP44]], align 4 -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[TMP51]], align 4, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP53]], i64 0, i64 0 +// CHECK2-NEXT: store i32 [[TMP59]], i32* [[ARRAYIDX_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP52]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP60:%.*]] = bitcast %struct.S* [[ARRAYIDX6_I]] to i8* +// CHECK2-NEXT: [[TMP61:%.*]] = bitcast %struct.S* [[TMP50]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP60]], i8* align 8 [[TMP61]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK2-NEXT: store i32 33, i32* [[TMP54]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK2: omp.inner.for.end.i: -// CHECK2-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP54:%.*]] = icmp ne i32 [[TMP53]], 0 -// CHECK2-NEXT: br i1 [[TMP54]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK2-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP64:%.*]] = icmp ne i32 [[TMP63]], 0 +// CHECK2-NEXT: br i1 [[TMP64]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: .omp.lastprivate.then.i: -// CHECK2-NEXT: [[TMP55:%.*]] = bitcast %struct.S* [[TMP27]] to i8* -// CHECK2-NEXT: [[TMP56:%.*]] = bitcast %struct.S* [[TMP40]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP55]], i8* align 8 [[TMP56]], i64 8, i1 false) #[[ATTR4]] -// CHECK2-NEXT: [[TMP57:%.*]] = load i32, i32* [[TMP41]], align 4 -// CHECK2-NEXT: store i32 [[TMP57]], i32* [[TMP29]], align 4 -// CHECK2-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP31]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP58:%.*]] = bitcast [2 x %struct.S]* [[TMP42]] to %struct.S* -// CHECK2-NEXT: [[TMP59:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[ARRAY_BEGIN_I]], i64 2 +// CHECK2-NEXT: [[TMP65:%.*]] = bitcast %struct.S* [[TMP37]] to i8* +// CHECK2-NEXT: [[TMP66:%.*]] = bitcast %struct.S* [[TMP50]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP65]], i8* align 8 [[TMP66]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK2-NEXT: [[TMP67:%.*]] = load i32, i32* [[TMP51]], align 4, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP67]], i32* [[TMP39]], align 4, !noalias !6 +// CHECK2-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP41]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP68:%.*]] = bitcast [2 x %struct.S]* [[TMP52]] to %struct.S* +// CHECK2-NEXT: [[TMP69:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[ARRAY_BEGIN_I]], i64 2 // CHECK2-NEXT: br label [[OMP_ARRAYCPY_BODY_I:%.*]] // CHECK2: omp.arraycpy.body.i: -// CHECK2-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S* [ [[TMP58]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] +// CHECK2-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S* [ [[TMP68]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] // CHECK2-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST_I:%.*]] = phi %struct.S* [ [[ARRAY_BEGIN_I]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] -// CHECK2-NEXT: [[TMP60:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* -// CHECK2-NEXT: [[TMP61:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP60]], i8* align 8 [[TMP61]], i64 8, i1 false) #[[ATTR4]] +// CHECK2-NEXT: [[TMP70:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* +// CHECK2-NEXT: [[TMP71:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP70]], i8* align 8 [[TMP71]], i64 8, i1 false) #[[ATTR4]], !noalias !6 // CHECK2-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT_I]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]], i32 1 // CHECK2-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT_I]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]], i32 1 -// CHECK2-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP59]] +// CHECK2-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP69]] // CHECK2-NEXT: br i1 [[OMP_ARRAYCPY_DONE_I]], label [[OMP_ARRAYCPY_DONE8_I:%.*]], label [[OMP_ARRAYCPY_BODY_I]] // CHECK2: omp.arraycpy.done8.i: -// CHECK2-NEXT: [[TMP62:%.*]] = bitcast [2 x i32]* [[TMP33]] to i8* -// CHECK2-NEXT: [[TMP63:%.*]] = bitcast [2 x i32]* [[TMP43]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP62]], i8* align 4 [[TMP63]], i64 8, i1 false) #[[ATTR4]] -// CHECK2-NEXT: [[TMP64:%.*]] = load i32, i32* [[TMP44]], align 4 -// CHECK2-NEXT: store i32 [[TMP64]], i32* [[TMP39]], align 4 +// CHECK2-NEXT: [[TMP72:%.*]] = bitcast [2 x i32]* [[TMP43]] to i8* +// CHECK2-NEXT: [[TMP73:%.*]] = bitcast [2 x i32]* [[TMP53]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP72]], i8* align 4 [[TMP73]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK2-NEXT: [[TMP74:%.*]] = load i32, i32* [[TMP54]], align 4, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP74]], i32* [[TMP49]], align 4, !noalias !6 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .omp_outlined..1.exit: // CHECK2-NEXT: ret i32 0 @@ -1669,95 +1684,100 @@ // CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 64 // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !28 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.3*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* @.omp_task_privates_map..4 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !28 -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: store %struct.anon.1* [[TMP8]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* -// CHECK2-NEXT: call void [[TMP25]](i8* [[TMP24]], i32** [[DOTLASTPRIV_PTR_ADDR_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP29:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP28]], align 8 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP30]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP33:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP32]], align 8 -// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 3 -// CHECK2-NEXT: [[TMP35:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP34]], align 8 -// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 3 -// CHECK2-NEXT: [[TMP37:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP36]], align 8 -// CHECK2-NEXT: [[TMP38:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP39:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP40:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP41:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP42]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !28 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META25]]), !noalias !20 +// CHECK2-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK2-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.3*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* @.omp_task_privates_map..4 to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META26]]), !noalias !20 +// CHECK2-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK2-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META27]]), !noalias !20 +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK2-NEXT: [[TMP31:%.*]] = call %struct.anon.1* @llvm.noalias.p0s_struct.anon.1s.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1* [[TMP8]], i8* [[TMP30]], %struct.anon.1** null, i64 0, metadata [[META28]]), !noalias !20 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK2-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !20 +// CHECK2-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store %struct.anon.1* [[TMP31]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP32:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* +// CHECK2-NEXT: call void [[TMP35]](i8* [[TMP34]], i32** [[DOTLASTPRIV_PTR_ADDR_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !20 +// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP39:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP38]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP41:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP40]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP43:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP42]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 3 +// CHECK2-NEXT: [[TMP45:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP44]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 3 +// CHECK2-NEXT: [[TMP47:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP46]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP48:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP49:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP50:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP51:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP52:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP52]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !20 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !28 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP44]] +// CHECK2-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !20 +// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP53]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP54]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK2-NEXT: store i32 [[TMP45]], i32* [[I_I]], align 4, !noalias !28 -// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[TMP38]], align 128 -// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP39]], i64 0, i64 0 -// CHECK2-NEXT: store i32 [[TMP46]], i32* [[ARRAYIDX_I]], align 4 -// CHECK2-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP40]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP47:%.*]] = bitcast %struct.S.0* [[ARRAYIDX5_I]] to i8* -// CHECK2-NEXT: [[TMP48:%.*]] = bitcast %struct.S.0* [[TMP41]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP47]], i8* align 4 [[TMP48]], i64 4, i1 false) #[[ATTR4]] -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !28 -// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP49]], 1 -// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !28 +// CHECK2-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !20 +// CHECK2-NEXT: store i32 [[TMP55]], i32* [[I_I]], align 4, !noalias !20 +// CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP48]], align 128, !noalias !20 +// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP49]], i64 0, i64 0 +// CHECK2-NEXT: store i32 [[TMP56]], i32* [[ARRAYIDX_I]], align 4, !noalias !20 +// CHECK2-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP50]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP57:%.*]] = bitcast %struct.S.0* [[ARRAYIDX5_I]] to i8* +// CHECK2-NEXT: [[TMP58:%.*]] = bitcast %struct.S.0* [[TMP51]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP57]], i8* align 4 [[TMP58]], i64 4, i1 false) #[[ATTR4]], !noalias !20 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !20 +// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP59]], 1 +// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !20 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK2: omp.inner.for.end.i: -// CHECK2-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !28 -// CHECK2-NEXT: [[TMP51:%.*]] = icmp ne i32 [[TMP50]], 0 -// CHECK2-NEXT: br i1 [[TMP51]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK2-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !20 +// CHECK2-NEXT: [[TMP61:%.*]] = icmp ne i32 [[TMP60]], 0 +// CHECK2-NEXT: br i1 [[TMP61]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK2: .omp.lastprivate.then.i: -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[TMP38]], align 128 -// CHECK2-NEXT: store i32 [[TMP52]], i32* [[TMP27]], align 128 -// CHECK2-NEXT: [[TMP53:%.*]] = bitcast [2 x i32]* [[TMP29]] to i8* -// CHECK2-NEXT: [[TMP54:%.*]] = bitcast [2 x i32]* [[TMP39]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP53]], i8* align 4 [[TMP54]], i64 8, i1 false) #[[ATTR4]] -// CHECK2-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP31]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP55:%.*]] = bitcast [2 x %struct.S.0]* [[TMP40]] to %struct.S.0* -// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN_I]], i64 2 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[TMP48]], align 128, !noalias !20 +// CHECK2-NEXT: store i32 [[TMP62]], i32* [[TMP37]], align 128, !noalias !20 +// CHECK2-NEXT: [[TMP63:%.*]] = bitcast [2 x i32]* [[TMP39]] to i8* +// CHECK2-NEXT: [[TMP64:%.*]] = bitcast [2 x i32]* [[TMP49]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP63]], i8* align 4 [[TMP64]], i64 8, i1 false) #[[ATTR4]], !noalias !20 +// CHECK2-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP41]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP65:%.*]] = bitcast [2 x %struct.S.0]* [[TMP50]] to %struct.S.0* +// CHECK2-NEXT: [[TMP66:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN_I]], i64 2 // CHECK2-NEXT: br label [[OMP_ARRAYCPY_BODY_I:%.*]] // CHECK2: omp.arraycpy.body.i: -// CHECK2-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[TMP55]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] +// CHECK2-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[TMP65]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] // CHECK2-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN_I]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] -// CHECK2-NEXT: [[TMP57:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* -// CHECK2-NEXT: [[TMP58:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP57]], i8* align 4 [[TMP58]], i64 4, i1 false) #[[ATTR4]] +// CHECK2-NEXT: [[TMP67:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* +// CHECK2-NEXT: [[TMP68:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP67]], i8* align 4 [[TMP68]], i64 4, i1 false) #[[ATTR4]], !noalias !20 // CHECK2-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT_I]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]], i32 1 // CHECK2-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT_I]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]], i32 1 -// CHECK2-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP56]] +// CHECK2-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP66]] // CHECK2-NEXT: br i1 [[OMP_ARRAYCPY_DONE_I]], label [[OMP_ARRAYCPY_DONE7_I:%.*]], label [[OMP_ARRAYCPY_BODY_I]] // CHECK2: omp.arraycpy.done7.i: -// CHECK2-NEXT: [[TMP59:%.*]] = bitcast %struct.S.0* [[TMP35]] to i8* -// CHECK2-NEXT: [[TMP60:%.*]] = bitcast %struct.S.0* [[TMP41]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP59]], i8* align 4 [[TMP60]], i64 4, i1 false) #[[ATTR4]] +// CHECK2-NEXT: [[TMP69:%.*]] = bitcast %struct.S.0* [[TMP45]] to i8* +// CHECK2-NEXT: [[TMP70:%.*]] = bitcast %struct.S.0* [[TMP51]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP69]], i8* align 4 [[TMP70]], i64 4, i1 false) #[[ATTR4]], !noalias !20 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK2: .omp_outlined..3.exit: // CHECK2-NEXT: ret i32 0 @@ -1983,66 +2003,71 @@ // CHECK3-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK3-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, double**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK3-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, double**, i32**)* -// CHECK3-NEXT: call void [[TMP25]](i8* [[TMP24]], double** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR3:[0-9]+]] -// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP27:%.*]] = load double*, double** [[TMP26]], align 8 -// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8 -// CHECK3-NEXT: [[TMP30:%.*]] = load double*, double** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP31:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP32]] to i32 -// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK3-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK3-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK3-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK3-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK3-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK3-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, double**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK3-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK3-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK3-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK3-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK3-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK3-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, double**, i32**)* +// CHECK3-NEXT: call void [[TMP35]](i8* [[TMP34]], double** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR3:[0-9]+]], !noalias !6 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP37:%.*]] = load double*, double** [[TMP36]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP40:%.*]] = load double*, double** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP42]] to i32 +// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK3: omp.inner.for.cond.i: -// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK3-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP33]] to i64 -// CHECK3-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP34]] +// CHECK3-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK3-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP43]] to i64 +// CHECK3-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP44]] // CHECK3-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK3: omp.inner.for.body.i: -// CHECK3-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK3-NEXT: store i32 [[TMP35]], i32* [[I_I]], align 4, !noalias !14 -// CHECK3-NEXT: store double 1.000000e+00, double* [[TMP30]], align 8 -// CHECK3-NEXT: store i32 11, i32* [[TMP31]], align 4 -// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP_I]], i32 0, i32 0 -// CHECK3-NEXT: store double* [[TMP30]], double** [[TMP36]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP_I]], i32 0, i32 1 -// CHECK3-NEXT: store i32* [[TMP31]], i32** [[TMP37]], align 8, !noalias !14 -// CHECK3-NEXT: call void @"_ZZZ4mainENK3$_0clEvENKUlvE_clEv"(%class.anon.0* nonnull align 8 dereferenceable(16) [[REF_TMP_I]]) #[[ATTR3]] -// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK3-NEXT: [[ADD3_I:%.*]] = add nsw i32 [[TMP38]], 1 -// CHECK3-NEXT: store i32 [[ADD3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK3-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK3-NEXT: store i32 [[TMP45]], i32* [[I_I]], align 4, !noalias !6 +// CHECK3-NEXT: store double 1.000000e+00, double* [[TMP40]], align 8, !noalias !6 +// CHECK3-NEXT: store i32 11, i32* [[TMP41]], align 4, !noalias !6 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP_I]], i32 0, i32 0 +// CHECK3-NEXT: store double* [[TMP40]], double** [[TMP46]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP_I]], i32 0, i32 1 +// CHECK3-NEXT: store i32* [[TMP41]], i32** [[TMP47]], align 8, !noalias !6 +// CHECK3-NEXT: call void @"_ZZZ4mainENK3$_0clEvENKUlvE_clEv"(%class.anon.0* nonnull align 8 dereferenceable(16) [[REF_TMP_I]]) #[[ATTR3]], !noalias !6 +// CHECK3-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK3-NEXT: [[ADD3_I:%.*]] = add nsw i32 [[TMP48]], 1 +// CHECK3-NEXT: store i32 [[ADD3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK3: omp.inner.for.end.i: -// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK3-NEXT: [[TMP40:%.*]] = icmp ne i32 [[TMP39]], 0 -// CHECK3-NEXT: br i1 [[TMP40]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK3-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK3-NEXT: [[TMP50:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK3-NEXT: br i1 [[TMP50]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK3: .omp.lastprivate.then.i: -// CHECK3-NEXT: [[TMP41:%.*]] = load double, double* [[TMP30]], align 8 -// CHECK3-NEXT: store volatile double [[TMP41]], double* [[TMP27]], align 8 -// CHECK3-NEXT: [[TMP42:%.*]] = load i32, i32* [[TMP31]], align 4 -// CHECK3-NEXT: store i32 [[TMP42]], i32* [[TMP29]], align 4 +// CHECK3-NEXT: [[TMP51:%.*]] = load double, double* [[TMP40]], align 8, !noalias !6 +// CHECK3-NEXT: store volatile double [[TMP51]], double* [[TMP37]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP52:%.*]] = load i32, i32* [[TMP41]], align 4, !noalias !6 +// CHECK3-NEXT: store i32 [[TMP52]], i32* [[TMP39]], align 4, !noalias !6 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK3: .omp_outlined..1.exit: // CHECK3-NEXT: ret i32 0 @@ -2212,84 +2237,89 @@ // CHECK4-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK4-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK4-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, double**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK4-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, double**, i32**)* -// CHECK4-NEXT: call void [[TMP25]](i8* [[TMP24]], double** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR4:[0-9]+]] -// CHECK4-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP27:%.*]] = load double*, double** [[TMP26]], align 8 -// CHECK4-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8 -// CHECK4-NEXT: [[TMP30:%.*]] = load double*, double** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP31:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP32]] to i32 -// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK4-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK4-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK4-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK4-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK4-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK4-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, double**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK4-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK4-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK4-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK4-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK4-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK4-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, double**, i32**)* +// CHECK4-NEXT: call void [[TMP35]](i8* [[TMP34]], double** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR4:[0-9]+]], !noalias !6 +// CHECK4-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP37:%.*]] = load double*, double** [[TMP36]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP40:%.*]] = load double*, double** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP42]] to i32 +// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK4: omp.inner.for.cond.i: -// CHECK4-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK4-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP33]] to i64 -// CHECK4-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP34]] +// CHECK4-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK4-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP43]] to i64 +// CHECK4-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP44]] // CHECK4-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK4: omp.inner.for.body.i: -// CHECK4-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK4-NEXT: store i32 [[TMP35]], i32* [[I_I]], align 4, !noalias !14 -// CHECK4-NEXT: store double 1.000000e+00, double* [[TMP30]], align 8 -// CHECK4-NEXT: store i32 11, i32* [[TMP31]], align 4 +// CHECK4-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK4-NEXT: store i32 [[TMP45]], i32* [[I_I]], align 4, !noalias !6 +// CHECK4-NEXT: store double 1.000000e+00, double* [[TMP40]], align 8, !noalias !6 +// CHECK4-NEXT: store i32 11, i32* [[TMP41]], align 4, !noalias !6 // CHECK4-NEXT: [[BLOCK_ISA_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 0 -// CHECK4-NEXT: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*), i8** [[BLOCK_ISA_I]], align 8, !noalias !14 +// CHECK4-NEXT: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*), i8** [[BLOCK_ISA_I]], align 8, !noalias !6 // CHECK4-NEXT: [[BLOCK_FLAGS_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 1 -// CHECK4-NEXT: store i32 1073741824, i32* [[BLOCK_FLAGS_I]], align 8, !noalias !14 +// CHECK4-NEXT: store i32 1073741824, i32* [[BLOCK_FLAGS_I]], align 8, !noalias !6 // CHECK4-NEXT: [[BLOCK_RESERVED_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 2 -// CHECK4-NEXT: store i32 0, i32* [[BLOCK_RESERVED_I]], align 4, !noalias !14 +// CHECK4-NEXT: store i32 0, i32* [[BLOCK_RESERVED_I]], align 4, !noalias !6 // CHECK4-NEXT: [[BLOCK_INVOKE_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 3 -// CHECK4-NEXT: store i8* bitcast (void (i8*)* @_block_invoke to i8*), i8** [[BLOCK_INVOKE_I]], align 8, !noalias !14 +// CHECK4-NEXT: store i8* bitcast (void (i8*)* @_block_invoke to i8*), i8** [[BLOCK_INVOKE_I]], align 8, !noalias !6 // CHECK4-NEXT: [[BLOCK_DESCRIPTOR_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 4 -// CHECK4-NEXT: store %struct.__block_descriptor* bitcast ({ i64, i64, i8*, i8* }* @__block_descriptor_tmp.2 to %struct.__block_descriptor*), %struct.__block_descriptor** [[BLOCK_DESCRIPTOR_I]], align 8, !noalias !14 +// CHECK4-NEXT: store %struct.__block_descriptor* bitcast ({ i64, i64, i8*, i8* }* @__block_descriptor_tmp.2 to %struct.__block_descriptor*), %struct.__block_descriptor** [[BLOCK_DESCRIPTOR_I]], align 8, !noalias !6 // CHECK4-NEXT: [[BLOCK_CAPTURED_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 5 -// CHECK4-NEXT: [[TMP36:%.*]] = load volatile double, double* [[TMP30]], align 8 -// CHECK4-NEXT: store volatile double [[TMP36]], double* [[BLOCK_CAPTURED_I]], align 8, !noalias !14 +// CHECK4-NEXT: [[TMP46:%.*]] = load volatile double, double* [[TMP40]], align 8, !noalias !6 +// CHECK4-NEXT: store volatile double [[TMP46]], double* [[BLOCK_CAPTURED_I]], align 8, !noalias !6 // CHECK4-NEXT: [[BLOCK_CAPTURED3_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 6 -// CHECK4-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4 -// CHECK4-NEXT: store i32 [[TMP37]], i32* [[BLOCK_CAPTURED3_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP38:%.*]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]] to void ()* -// CHECK4-NEXT: [[BLOCK_LITERAL_I:%.*]] = bitcast void ()* [[TMP38]] to %struct.__block_literal_generic* -// CHECK4-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], %struct.__block_literal_generic* [[BLOCK_LITERAL_I]], i32 0, i32 3 -// CHECK4-NEXT: [[TMP40:%.*]] = bitcast %struct.__block_literal_generic* [[BLOCK_LITERAL_I]] to i8* -// CHECK4-NEXT: [[TMP41:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP42:%.*]] = bitcast i8* [[TMP41]] to void (i8*)* -// CHECK4-NEXT: call void [[TMP42]](i8* [[TMP40]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK4-NEXT: [[ADD4_I:%.*]] = add nsw i32 [[TMP43]], 1 -// CHECK4-NEXT: store i32 [[ADD4_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK4-NEXT: [[TMP47:%.*]] = load i32, i32* [[TMP41]], align 4, !noalias !6 +// CHECK4-NEXT: store i32 [[TMP47]], i32* [[BLOCK_CAPTURED3_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP48:%.*]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]] to void ()* +// CHECK4-NEXT: [[BLOCK_LITERAL_I:%.*]] = bitcast void ()* [[TMP48]] to %struct.__block_literal_generic* +// CHECK4-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], %struct.__block_literal_generic* [[BLOCK_LITERAL_I]], i32 0, i32 3 +// CHECK4-NEXT: [[TMP50:%.*]] = bitcast %struct.__block_literal_generic* [[BLOCK_LITERAL_I]] to i8* +// CHECK4-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP49]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP52:%.*]] = bitcast i8* [[TMP51]] to void (i8*)* +// CHECK4-NEXT: call void [[TMP52]](i8* [[TMP50]]) #[[ATTR4]], !noalias !6 +// CHECK4-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK4-NEXT: [[ADD4_I:%.*]] = add nsw i32 [[TMP53]], 1 +// CHECK4-NEXT: store i32 [[ADD4_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK4: omp.inner.for.end.i: -// CHECK4-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK4-NEXT: [[TMP45:%.*]] = icmp ne i32 [[TMP44]], 0 -// CHECK4-NEXT: br i1 [[TMP45]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK4-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK4-NEXT: [[TMP55:%.*]] = icmp ne i32 [[TMP54]], 0 +// CHECK4-NEXT: br i1 [[TMP55]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK4: .omp.lastprivate.then.i: -// CHECK4-NEXT: [[TMP46:%.*]] = load double, double* [[TMP30]], align 8 -// CHECK4-NEXT: store volatile double [[TMP46]], double* [[TMP27]], align 8 -// CHECK4-NEXT: [[TMP47:%.*]] = load i32, i32* [[TMP31]], align 4 -// CHECK4-NEXT: store i32 [[TMP47]], i32* [[TMP29]], align 4 +// CHECK4-NEXT: [[TMP56:%.*]] = load double, double* [[TMP40]], align 8, !noalias !6 +// CHECK4-NEXT: store volatile double [[TMP56]], double* [[TMP37]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP57:%.*]] = load i32, i32* [[TMP41]], align 4, !noalias !6 +// CHECK4-NEXT: store i32 [[TMP57]], i32* [[TMP39]], align 4, !noalias !6 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK4: .omp_outlined..1.exit: // CHECK4-NEXT: ret i32 0 @@ -2446,61 +2476,66 @@ // CHECK5-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK5-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, float***, %struct.St***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK5-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK5-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK5-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, float***, %struct.St***)* -// CHECK5-NEXT: call void [[TMP27]](i8* [[TMP26]], float*** [[DOTLASTPRIV_PTR_ADDR_I]], %struct.St*** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR2:[0-9]+]] -// CHECK5-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK5-NEXT: [[TMP29:%.*]] = load float**, float*** [[TMP28]], align 8 -// CHECK5-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK5-NEXT: [[TMP31:%.*]] = load %struct.St**, %struct.St*** [[TMP30]], align 8 -// CHECK5-NEXT: [[TMP32:%.*]] = load float**, float*** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP33:%.*]] = load %struct.St**, %struct.St*** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP34]] to i32 -// CHECK5-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK5-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK5-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK5-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK5-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK5-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK5-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, float***, %struct.St***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK5-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK5-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK5-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK5-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK5-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK5-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK5-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, float***, %struct.St***)* +// CHECK5-NEXT: call void [[TMP37]](i8* [[TMP36]], float*** [[DOTLASTPRIV_PTR_ADDR_I]], %struct.St*** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR2:[0-9]+]], !noalias !6 +// CHECK5-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK5-NEXT: [[TMP39:%.*]] = load float**, float*** [[TMP38]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK5-NEXT: [[TMP41:%.*]] = load %struct.St**, %struct.St*** [[TMP40]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP42:%.*]] = load float**, float*** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP43:%.*]] = load %struct.St**, %struct.St*** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP44]] to i32 +// CHECK5-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK5: omp.inner.for.cond.i: -// CHECK5-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK5-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP35]] to i64 -// CHECK5-NEXT: [[TMP36:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP36]] +// CHECK5-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK5-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP45]] to i64 +// CHECK5-NEXT: [[TMP46:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP46]] // CHECK5-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK5: omp.inner.for.body.i: -// CHECK5-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK5-NEXT: store i32 [[TMP37]], i32* [[I_I]], align 4, !noalias !14 -// CHECK5-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK5-NEXT: [[ADD3_I:%.*]] = add nsw i32 [[TMP38]], 1 -// CHECK5-NEXT: store i32 [[ADD3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK5-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK5-NEXT: store i32 [[TMP47]], i32* [[I_I]], align 4, !noalias !6 +// CHECK5-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK5-NEXT: [[ADD3_I:%.*]] = add nsw i32 [[TMP48]], 1 +// CHECK5-NEXT: store i32 [[ADD3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK5: omp.inner.for.end.i: -// CHECK5-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK5-NEXT: [[TMP40:%.*]] = icmp ne i32 [[TMP39]], 0 -// CHECK5-NEXT: br i1 [[TMP40]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK5-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK5-NEXT: [[TMP50:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK5-NEXT: br i1 [[TMP50]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK5: .omp.lastprivate.then.i: -// CHECK5-NEXT: [[TMP41:%.*]] = load float*, float** [[TMP32]], align 8 -// CHECK5-NEXT: store float* [[TMP41]], float** [[TMP29]], align 8 -// CHECK5-NEXT: [[TMP42:%.*]] = load %struct.St*, %struct.St** [[TMP33]], align 8 -// CHECK5-NEXT: store %struct.St* [[TMP42]], %struct.St** [[TMP31]], align 8 +// CHECK5-NEXT: [[TMP51:%.*]] = load float*, float** [[TMP42]], align 8, !noalias !6 +// CHECK5-NEXT: store float* [[TMP51]], float** [[TMP39]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP52:%.*]] = load %struct.St*, %struct.St** [[TMP43]], align 8, !noalias !6 +// CHECK5-NEXT: store %struct.St* [[TMP52]], %struct.St** [[TMP41]], align 8, !noalias !6 // CHECK5-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK5: .omp_outlined..1.exit: // CHECK5-NEXT: ret i32 0 @@ -2634,55 +2669,60 @@ // CHECK6-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK6-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK6-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK6-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i32**)* -// CHECK6-NEXT: call void [[TMP25]](i8* [[TMP24]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2:[0-9]+]] -// CHECK6-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK6-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK6-NEXT: [[TMP28:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP29]] to i32 -// CHECK6-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK6-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK6-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK6-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK6-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK6-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK6-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK6-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK6-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK6-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK6-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK6-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK6-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, i32**)* +// CHECK6-NEXT: call void [[TMP35]](i8* [[TMP34]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2:[0-9]+]], !noalias !6 +// CHECK6-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK6-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP38:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP39]] to i32 +// CHECK6-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK6: omp.inner.for.cond.i: -// CHECK6-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK6-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP30]] to i64 -// CHECK6-NEXT: [[TMP31:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP31]] +// CHECK6-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK6-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP40]] to i64 +// CHECK6-NEXT: [[TMP41:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP41]] // CHECK6-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK6: omp.inner.for.body.i: -// CHECK6-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK6-NEXT: store i32 [[TMP32]], i32* [[I_I]], align 4, !noalias !14 -// CHECK6-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK6-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP33]], 1 -// CHECK6-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK6-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK6-NEXT: store i32 [[TMP42]], i32* [[I_I]], align 4, !noalias !6 +// CHECK6-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK6-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP43]], 1 +// CHECK6-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK6: omp.inner.for.end.i: -// CHECK6-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK6-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 -// CHECK6-NEXT: br i1 [[TMP35]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK6-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK6-NEXT: [[TMP45:%.*]] = icmp ne i32 [[TMP44]], 0 +// CHECK6-NEXT: br i1 [[TMP45]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK6: .omp.lastprivate.then.i: -// CHECK6-NEXT: store i32 10, i32* [[I_I]], align 4, !noalias !14 -// CHECK6-NEXT: [[TMP36:%.*]] = load i32, i32* [[I_I]], align 4, !noalias !14 -// CHECK6-NEXT: store i32 [[TMP36]], i32* [[TMP27]], align 4 +// CHECK6-NEXT: store i32 10, i32* [[I_I]], align 4, !noalias !6 +// CHECK6-NEXT: [[TMP46:%.*]] = load i32, i32* [[I_I]], align 4, !noalias !6 +// CHECK6-NEXT: store i32 [[TMP46]], i32* [[TMP37]], align 4, !noalias !6 // CHECK6-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK6: .omp_outlined..1.exit: // CHECK6-NEXT: ret i32 0 Index: clang/test/OpenMP/parallel_master_taskloop_private_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_private_codegen.cpp +++ clang/test/OpenMP/parallel_master_taskloop_private_codegen.cpp @@ -228,7 +228,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) @@ -351,7 +352,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/parallel_master_taskloop_simd_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_simd_codegen.cpp +++ clang/test/OpenMP/parallel_master_taskloop_simd_codegen.cpp @@ -204,40 +204,41 @@ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META9]]), !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP24]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP25]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP26:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK1-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK1-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK1-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK1-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP11:![0-9]+]] // CHECK1: .omp_outlined..1.exit: // CHECK1-NEXT: ret i32 0 // @@ -320,40 +321,41 @@ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META27:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META29:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !31 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK1-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META22]]), !noalias !19 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP24]], %struct.anon.0** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK1-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !19 +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store %struct.anon.0* [[TMP25]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: [[TMP26:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !19 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK1-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31, !llvm.access.group !32 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK1-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK1-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !19, !llvm.access.group !24 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK1-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK1-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK1-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK1-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK1-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK1-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP25:![0-9]+]] // CHECK1: .omp_outlined..3.exit: // CHECK1-NEXT: ret i32 0 // @@ -523,129 +525,134 @@ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META39:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META41:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META43:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META45:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !47 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !47 -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i32**)* -// CHECK1-NEXT: call void [[TMP25]](i8* [[TMP24]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2]] -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP22]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4 -// CHECK1-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP32]], align 8 -// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP33]], align 4 -// CHECK1-NEXT: store i32 [[TMP34]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP36:%.*]] = load i8***, i8**** [[TMP35]], align 8 -// CHECK1-NEXT: [[TMP37:%.*]] = load i8**, i8*** [[TMP36]], align 8 -// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP39]], align 4 -// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP40]] to i64 -// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP37]], i64 [[IDXPROM_I]] -// CHECK1-NEXT: [[TMP41:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8 -// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP43:%.*]] = load i32*, i32** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = load i32, i32* [[TMP43]], align 4 -// CHECK1-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP44]] to i64 -// CHECK1-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP41]], i64 [[IDXPROM4_I]] -// CHECK1-NEXT: [[TMP45:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1 -// CHECK1-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP45]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK1-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK1-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK1-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK1-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP47]], [[TMP48]] +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META28]]), !noalias !31 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META36:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META36]]), !noalias !31 +// CHECK1-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META37:![0-9]+]]) +// CHECK1-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META37]]), !noalias !31 +// CHECK1-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META38:![0-9]+]]) +// CHECK1-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META38]]), !noalias !31 +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META39:![0-9]+]]) +// CHECK1-NEXT: [[TMP31:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP30]], %struct.anon.2** null, i64 0, metadata [[META39]]), !noalias !31 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !31 +// CHECK1-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 +// CHECK1-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: store %struct.anon.2* [[TMP31]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP32:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, i32**)* +// CHECK1-NEXT: call void [[TMP35]](i8* [[TMP34]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2]], !noalias !31 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP32]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP38:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP40:%.*]] = load i32*, i32** [[TMP39]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP40]], align 4, !noalias !31 +// CHECK1-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP43:%.*]] = load i32*, i32** [[TMP42]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP44:%.*]] = load i32, i32* [[TMP43]], align 4, !noalias !31 +// CHECK1-NEXT: store i32 [[TMP44]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP46:%.*]] = load i8***, i8**** [[TMP45]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8**, i8*** [[TMP46]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP49:%.*]] = load i32*, i32** [[TMP48]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[TMP49]], align 4, !noalias !31 +// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP50]] to i64 +// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP47]], i64 [[IDXPROM_I]] +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP53:%.*]] = load i32*, i32** [[TMP52]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !noalias !31 +// CHECK1-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP54]] to i64 +// CHECK1-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP51]], i64 [[IDXPROM4_I]] +// CHECK1-NEXT: [[TMP55:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1, !noalias !31 +// CHECK1-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP55]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK1-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK1-NEXT: [[TMP57:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP57]], [[TMP58]] // CHECK1-NEXT: [[SUB9_I:%.*]] = sub i32 [[SUB8_I]], 1 // CHECK1-NEXT: [[CONV11_I:%.*]] = zext i32 [[SUB8_I]] to i64 // CHECK1-NEXT: [[MUL_I:%.*]] = mul nsw i64 [[CONV7_I]], [[CONV11_I]] // CHECK1-NEXT: [[SUB12_I:%.*]] = sub nsw i64 [[MUL_I]], 1 -// CHECK1-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !47 -// CHECK1-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !47 -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK1-NEXT: store i32 [[TMP49]], i32* [[J_I]], align 4, !noalias !47 -// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP50]] +// CHECK1-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !31 +// CHECK1-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK1-NEXT: store i32 [[TMP59]], i32* [[J_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP60]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[LAND_LHS_TRUE_I:%.*]], label [[TASKLOOP_IF_END_I:%.*]] // CHECK1: land.lhs.true.i: -// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK1-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP51]], [[TMP52]] +// CHECK1-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP61]], [[TMP62]] // CHECK1-NEXT: br i1 [[CMP13_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[TASKLOOP_IF_END_I]] // CHECK1: taskloop.if.then.i: -// CHECK1-NEXT: [[TMP53:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !47 -// CHECK1-NEXT: store i64 [[TMP53]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP55:%.*]] = load i32*, i32** [[TMP54]], align 8 -// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP57:%.*]] = load i8***, i8**** [[TMP56]], align 8 +// CHECK1-NEXT: [[TMP63:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 +// CHECK1-NEXT: store i64 [[TMP63]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP65:%.*]] = load i32*, i32** [[TMP64]], align 8, !noalias !31 +// CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP67:%.*]] = load i8***, i8**** [[TMP66]], align 8, !noalias !31 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP58:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[TMP59:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP58]], [[TMP59]] +// CHECK1-NEXT: [[TMP68:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[TMP69:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP68]], [[TMP69]] // CHECK1-NEXT: br i1 [[CMP16_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP60:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP61]], [[TMP62]] +// CHECK1-NEXT: [[TMP70:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[TMP71:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[TMP72:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP71]], [[TMP72]] // CHECK1-NEXT: [[SUB18_I:%.*]] = sub i32 [[SUB17_I]], 1 // CHECK1-NEXT: [[CONV22_I:%.*]] = zext i32 [[SUB17_I]] to i64 -// CHECK1-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP60]], [[CONV22_I]] +// CHECK1-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP70]], [[CONV22_I]] // CHECK1-NEXT: [[CONV26_I:%.*]] = trunc i64 [[DIV23_I]] to i32 -// CHECK1-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP63]] to i64 -// CHECK1-NEXT: [[TMP64:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[TMP65:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[TMP66:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[TMP67:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP66]], [[TMP67]] +// CHECK1-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[TMP73:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP73]] to i64 +// CHECK1-NEXT: [[TMP74:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[TMP75:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[TMP76:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[TMP77:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP76]], [[TMP77]] // CHECK1-NEXT: [[SUB29_I:%.*]] = sub i32 [[SUB28_I]], 1 // CHECK1-NEXT: [[CONV33_I:%.*]] = zext i32 [[SUB28_I]] to i64 -// CHECK1-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP65]], [[CONV33_I]] -// CHECK1-NEXT: [[TMP68:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[TMP69:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP68]], [[TMP69]] +// CHECK1-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP75]], [[CONV33_I]] +// CHECK1-NEXT: [[TMP78:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[TMP79:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP78]], [[TMP79]] // CHECK1-NEXT: [[SUB36_I:%.*]] = sub i32 [[SUB35_I]], 1 // CHECK1-NEXT: [[CONV40_I:%.*]] = zext i32 [[SUB35_I]] to i64 // CHECK1-NEXT: [[MUL41_I:%.*]] = mul nsw i64 [[DIV34_I]], [[CONV40_I]] -// CHECK1-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP64]], [[MUL41_I]] +// CHECK1-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP74]], [[MUL41_I]] // CHECK1-NEXT: [[ADD44_I:%.*]] = add nsw i64 [[CONV27_I]], [[SUB42_I]] // CHECK1-NEXT: [[CONV45_I:%.*]] = trunc i64 [[ADD44_I]] to i32 -// CHECK1-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[TMP70:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP70]], 1 -// CHECK1-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK1-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[TMP80:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP80]], 1 +// CHECK1-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP41:![0-9]+]] // CHECK1: omp.inner.for.end.i: // CHECK1-NEXT: br label [[TASKLOOP_IF_END_I]] // CHECK1: taskloop.if.end.i: -// CHECK1-NEXT: [[TMP71:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !47 -// CHECK1-NEXT: [[TMP72:%.*]] = icmp ne i32 [[TMP71]], 0 -// CHECK1-NEXT: br i1 [[TMP72]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] +// CHECK1-NEXT: [[TMP81:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 +// CHECK1-NEXT: [[TMP82:%.*]] = icmp ne i32 [[TMP81]], 0 +// CHECK1-NEXT: br i1 [[TMP82]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] // CHECK1: .omp.lastprivate.then.i: // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__6_EXIT]] // CHECK1: .omp_outlined..6.exit: @@ -830,61 +837,62 @@ // CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META51:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META54:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !62 -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON_4:%.*]], %struct.anon.4* [[TMP20]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.S*, %struct.S** [[TMP21]], align 8 -// CHECK1-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !62 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP20]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = load i32*, i32** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK1-NEXT: store i32 [[TMP25]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !62 -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !62 -// CHECK1-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP26]], 1 -// CHECK1-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !62 -// CHECK1-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !62 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i32 0, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !62 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP28]] +// CHECK1-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META43:![0-9]+]]) +// CHECK1-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META43]]), !noalias !46 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META49:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META49]]), !noalias !46 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META50:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP24]], %struct.anon.4** null, i64 0, metadata [[META50]]), !noalias !46 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !46 +// CHECK1-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !46 +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: store %struct.anon.4* [[TMP25]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: [[TMP26:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_4:%.*]], %struct.anon.4* [[TMP26]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP28:%.*]] = load %struct.S*, %struct.S** [[TMP27]], align 8, !noalias !46 +// CHECK1-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !46 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP26]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8, !noalias !46 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4, !noalias !46 +// CHECK1-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !46 +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !46 +// CHECK1-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP32]], 1 +// CHECK1-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !46 +// CHECK1-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !46 +// CHECK1-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !46 +// CHECK1-NEXT: store i32 0, i32* [[TMP33]], align 4, !noalias !46 +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !46 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP34]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK1: taskloop.if.then.i: -// CHECK1-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !62 -// CHECK1-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP29]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !62 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP20]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 +// CHECK1-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !46 +// CHECK1-NEXT: [[TMP35:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !46 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP35]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !46 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP26]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !46 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !62, !llvm.access.group !63 -// CHECK1-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP32]] to i64 -// CHECK1-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !62, !llvm.access.group !63 -// CHECK1-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP33]] +// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK1-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP38]] to i64 +// CHECK1-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !46, !llvm.access.group !51 +// CHECK1-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP39]] // CHECK1-NEXT: br i1 [[CMP8_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !62, !llvm.access.group !63 -// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !62, !llvm.access.group !63 -// CHECK1-NEXT: store i32 [[TMP34]], i32* [[TMP35]], align 4, !llvm.access.group !63 -// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !62, !llvm.access.group !63 -// CHECK1-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP36]], 1 -// CHECK1-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !62, !llvm.access.group !63 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP64:![0-9]+]] +// CHECK1-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !46, !llvm.access.group !51 +// CHECK1-NEXT: store i32 [[TMP40]], i32* [[TMP41]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK1-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK1-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP42]], 1 +// CHECK1-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP52:![0-9]+]] // CHECK1: omp.inner.for.end.i: // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT]] // CHECK1: .omp_outlined..9.exit: @@ -1049,40 +1057,41 @@ // CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META9]]), !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP24]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP25]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP26:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK2-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK2-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK2-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK2-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP11:![0-9]+]] // CHECK2: .omp_outlined..1.exit: // CHECK2-NEXT: ret i32 0 // @@ -1165,40 +1174,41 @@ // CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META27:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META29:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !31 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 -// CHECK2-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK2-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META22]]), !noalias !19 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP24]], %struct.anon.0** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK2-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !19 +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store %struct.anon.0* [[TMP25]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: [[TMP26:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !19 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK2-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31, !llvm.access.group !32 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK2-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK2-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !19, !llvm.access.group !24 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK2-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK2-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK2-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK2-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK2-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK2-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP25:![0-9]+]] // CHECK2: .omp_outlined..3.exit: // CHECK2-NEXT: ret i32 0 // @@ -1368,129 +1378,134 @@ // CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META39:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META41:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META43:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META45:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !47 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !47 -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i32**)* -// CHECK2-NEXT: call void [[TMP25]](i8* [[TMP24]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2]] -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP22]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4 -// CHECK2-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP32]], align 8 -// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP33]], align 4 -// CHECK2-NEXT: store i32 [[TMP34]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK2-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP36:%.*]] = load i8***, i8**** [[TMP35]], align 8 -// CHECK2-NEXT: [[TMP37:%.*]] = load i8**, i8*** [[TMP36]], align 8 -// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP39]], align 4 -// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP40]] to i64 -// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP37]], i64 [[IDXPROM_I]] -// CHECK2-NEXT: [[TMP41:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8 -// CHECK2-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP43:%.*]] = load i32*, i32** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = load i32, i32* [[TMP43]], align 4 -// CHECK2-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP44]] to i64 -// CHECK2-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP41]], i64 [[IDXPROM4_I]] -// CHECK2-NEXT: [[TMP45:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1 -// CHECK2-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP45]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK2-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK2-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK2-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP47]], [[TMP48]] +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META28]]), !noalias !31 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META36:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META36]]), !noalias !31 +// CHECK2-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META37:![0-9]+]]) +// CHECK2-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META37]]), !noalias !31 +// CHECK2-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META38:![0-9]+]]) +// CHECK2-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META38]]), !noalias !31 +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META39:![0-9]+]]) +// CHECK2-NEXT: [[TMP31:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP30]], %struct.anon.2** null, i64 0, metadata [[META39]]), !noalias !31 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !31 +// CHECK2-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 +// CHECK2-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: store %struct.anon.2* [[TMP31]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP32:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, i32**)* +// CHECK2-NEXT: call void [[TMP35]](i8* [[TMP34]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2]], !noalias !31 +// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP32]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP38:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP40:%.*]] = load i32*, i32** [[TMP39]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP40]], align 4, !noalias !31 +// CHECK2-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK2-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP43:%.*]] = load i32*, i32** [[TMP42]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP44:%.*]] = load i32, i32* [[TMP43]], align 4, !noalias !31 +// CHECK2-NEXT: store i32 [[TMP44]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP46:%.*]] = load i8***, i8**** [[TMP45]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8**, i8*** [[TMP46]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP49:%.*]] = load i32*, i32** [[TMP48]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP50:%.*]] = load i32, i32* [[TMP49]], align 4, !noalias !31 +// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP50]] to i64 +// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP47]], i64 [[IDXPROM_I]] +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP53:%.*]] = load i32*, i32** [[TMP52]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !noalias !31 +// CHECK2-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP54]] to i64 +// CHECK2-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP51]], i64 [[IDXPROM4_I]] +// CHECK2-NEXT: [[TMP55:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1, !noalias !31 +// CHECK2-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP55]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK2-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK2-NEXT: [[TMP57:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP57]], [[TMP58]] // CHECK2-NEXT: [[SUB9_I:%.*]] = sub i32 [[SUB8_I]], 1 // CHECK2-NEXT: [[CONV11_I:%.*]] = zext i32 [[SUB8_I]] to i64 // CHECK2-NEXT: [[MUL_I:%.*]] = mul nsw i64 [[CONV7_I]], [[CONV11_I]] // CHECK2-NEXT: [[SUB12_I:%.*]] = sub nsw i64 [[MUL_I]], 1 -// CHECK2-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !47 -// CHECK2-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !47 -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK2-NEXT: store i32 [[TMP49]], i32* [[J_I]], align 4, !noalias !47 -// CHECK2-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP50]] +// CHECK2-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !31 +// CHECK2-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK2-NEXT: store i32 [[TMP59]], i32* [[J_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP60]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[LAND_LHS_TRUE_I:%.*]], label [[TASKLOOP_IF_END_I:%.*]] // CHECK2: land.lhs.true.i: -// CHECK2-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK2-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP51]], [[TMP52]] +// CHECK2-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP61]], [[TMP62]] // CHECK2-NEXT: br i1 [[CMP13_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[TASKLOOP_IF_END_I]] // CHECK2: taskloop.if.then.i: -// CHECK2-NEXT: [[TMP53:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !47 -// CHECK2-NEXT: store i64 [[TMP53]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK2-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP55:%.*]] = load i32*, i32** [[TMP54]], align 8 -// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP57:%.*]] = load i8***, i8**** [[TMP56]], align 8 +// CHECK2-NEXT: [[TMP63:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 +// CHECK2-NEXT: store i64 [[TMP63]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP65:%.*]] = load i32*, i32** [[TMP64]], align 8, !noalias !31 +// CHECK2-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP67:%.*]] = load i8***, i8**** [[TMP66]], align 8, !noalias !31 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP58:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[TMP59:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP58]], [[TMP59]] +// CHECK2-NEXT: [[TMP68:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[TMP69:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP68]], [[TMP69]] // CHECK2-NEXT: br i1 [[CMP16_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP60:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP61]], [[TMP62]] +// CHECK2-NEXT: [[TMP70:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[TMP71:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[TMP72:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP71]], [[TMP72]] // CHECK2-NEXT: [[SUB18_I:%.*]] = sub i32 [[SUB17_I]], 1 // CHECK2-NEXT: [[CONV22_I:%.*]] = zext i32 [[SUB17_I]] to i64 -// CHECK2-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP60]], [[CONV22_I]] +// CHECK2-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP70]], [[CONV22_I]] // CHECK2-NEXT: [[CONV26_I:%.*]] = trunc i64 [[DIV23_I]] to i32 -// CHECK2-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP63]] to i64 -// CHECK2-NEXT: [[TMP64:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[TMP65:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[TMP66:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[TMP67:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP66]], [[TMP67]] +// CHECK2-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[TMP73:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP73]] to i64 +// CHECK2-NEXT: [[TMP74:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[TMP75:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[TMP76:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[TMP77:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP76]], [[TMP77]] // CHECK2-NEXT: [[SUB29_I:%.*]] = sub i32 [[SUB28_I]], 1 // CHECK2-NEXT: [[CONV33_I:%.*]] = zext i32 [[SUB28_I]] to i64 -// CHECK2-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP65]], [[CONV33_I]] -// CHECK2-NEXT: [[TMP68:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[TMP69:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP68]], [[TMP69]] +// CHECK2-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP75]], [[CONV33_I]] +// CHECK2-NEXT: [[TMP78:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[TMP79:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP78]], [[TMP79]] // CHECK2-NEXT: [[SUB36_I:%.*]] = sub i32 [[SUB35_I]], 1 // CHECK2-NEXT: [[CONV40_I:%.*]] = zext i32 [[SUB35_I]] to i64 // CHECK2-NEXT: [[MUL41_I:%.*]] = mul nsw i64 [[DIV34_I]], [[CONV40_I]] -// CHECK2-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP64]], [[MUL41_I]] +// CHECK2-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP74]], [[MUL41_I]] // CHECK2-NEXT: [[ADD44_I:%.*]] = add nsw i64 [[CONV27_I]], [[SUB42_I]] // CHECK2-NEXT: [[CONV45_I:%.*]] = trunc i64 [[ADD44_I]] to i32 -// CHECK2-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[TMP70:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP70]], 1 -// CHECK2-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK2-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[TMP80:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP80]], 1 +// CHECK2-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP41:![0-9]+]] // CHECK2: omp.inner.for.end.i: // CHECK2-NEXT: br label [[TASKLOOP_IF_END_I]] // CHECK2: taskloop.if.end.i: -// CHECK2-NEXT: [[TMP71:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !47 -// CHECK2-NEXT: [[TMP72:%.*]] = icmp ne i32 [[TMP71]], 0 -// CHECK2-NEXT: br i1 [[TMP72]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] +// CHECK2-NEXT: [[TMP81:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 +// CHECK2-NEXT: [[TMP82:%.*]] = icmp ne i32 [[TMP81]], 0 +// CHECK2-NEXT: br i1 [[TMP82]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] // CHECK2: .omp.lastprivate.then.i: // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__6_EXIT]] // CHECK2: .omp_outlined..6.exit: @@ -1655,61 +1670,62 @@ // CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META51:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META54:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !62 -// CHECK2-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON_4:%.*]], %struct.anon.4* [[TMP20]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.S*, %struct.S** [[TMP21]], align 8 -// CHECK2-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !62 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP20]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = load i32*, i32** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK2-NEXT: store i32 [[TMP25]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !62 -// CHECK2-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !62 -// CHECK2-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP26]], 1 -// CHECK2-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !62 -// CHECK2-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !62 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i32 0, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !62 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP28]] +// CHECK2-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META43:![0-9]+]]) +// CHECK2-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META43]]), !noalias !46 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META49:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META49]]), !noalias !46 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META50:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP24]], %struct.anon.4** null, i64 0, metadata [[META50]]), !noalias !46 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !46 +// CHECK2-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !46 +// CHECK2-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: store %struct.anon.4* [[TMP25]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: [[TMP26:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_4:%.*]], %struct.anon.4* [[TMP26]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP28:%.*]] = load %struct.S*, %struct.S** [[TMP27]], align 8, !noalias !46 +// CHECK2-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !46 +// CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP26]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8, !noalias !46 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4, !noalias !46 +// CHECK2-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !46 +// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !46 +// CHECK2-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP32]], 1 +// CHECK2-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !46 +// CHECK2-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !46 +// CHECK2-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !46 +// CHECK2-NEXT: store i32 0, i32* [[TMP33]], align 4, !noalias !46 +// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !46 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP34]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK2: taskloop.if.then.i: -// CHECK2-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !62 -// CHECK2-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP29]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !62 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP20]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 +// CHECK2-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !46 +// CHECK2-NEXT: [[TMP35:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !46 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP35]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !46 +// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP26]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !46 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !62, !llvm.access.group !63 -// CHECK2-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP32]] to i64 -// CHECK2-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !62, !llvm.access.group !63 -// CHECK2-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP33]] +// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK2-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP38]] to i64 +// CHECK2-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !46, !llvm.access.group !51 +// CHECK2-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP39]] // CHECK2-NEXT: br i1 [[CMP8_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !62, !llvm.access.group !63 -// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !62, !llvm.access.group !63 -// CHECK2-NEXT: store i32 [[TMP34]], i32* [[TMP35]], align 4, !llvm.access.group !63 -// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !62, !llvm.access.group !63 -// CHECK2-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP36]], 1 -// CHECK2-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !62, !llvm.access.group !63 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP64:![0-9]+]] +// CHECK2-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !46, !llvm.access.group !51 +// CHECK2-NEXT: store i32 [[TMP40]], i32* [[TMP41]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK2-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK2-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP42]], 1 +// CHECK2-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !46, !llvm.access.group !51 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP52:![0-9]+]] // CHECK2: omp.inner.for.end.i: // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT]] // CHECK2: .omp_outlined..9.exit: @@ -1894,40 +1910,41 @@ // CHECK3-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK3-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK3-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK3-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK3-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK3-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK3-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META9]]), !noalias !6 +// CHECK3-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK3-NEXT: [[TMP25:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP24]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK3-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK3-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store %struct.anon* [[TMP25]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP26:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK3: omp.inner.for.cond.i: -// CHECK3-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK3-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK3-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK3-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK3-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK3-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK3-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK3: omp.inner.for.body.i: -// CHECK3-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK3-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !14 -// CHECK3-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK3-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK3-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK3-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !6 +// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK3-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK3-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP11:![0-9]+]] // CHECK3: .omp_outlined..1.exit: // CHECK3-NEXT: ret i32 0 // @@ -2010,40 +2027,41 @@ // CHECK3-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK3-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META27:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META29:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !31 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 -// CHECK3-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: [[TMP20:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 -// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK3-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK3-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK3-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META22]]), !noalias !19 +// CHECK3-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK3-NEXT: [[TMP25:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP24]], %struct.anon.0** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: store %struct.anon.0* [[TMP25]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: [[TMP26:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !19 +// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !19 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK3: omp.inner.for.cond.i: -// CHECK3-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK3-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK3-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31, !llvm.access.group !32 -// CHECK3-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK3-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK3-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK3-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !19, !llvm.access.group !24 +// CHECK3-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK3-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK3: omp.inner.for.body.i: -// CHECK3-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK3-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK3-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK3-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK3-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK3-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK3-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK3-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP25:![0-9]+]] // CHECK3: .omp_outlined..3.exit: // CHECK3-NEXT: ret i32 0 // @@ -2218,179 +2236,184 @@ // CHECK3-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK3-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META39:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META41:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META43:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META45:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !47 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !47 -// CHECK3-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP22:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i32**)* -// CHECK3-NEXT: call void [[TMP25]](i8* [[TMP24]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2]] -// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP22]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK3-NEXT: [[TMP28:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8 -// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4 -// CHECK3-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP32]], align 8 -// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP33]], align 4 -// CHECK3-NEXT: store i32 [[TMP34]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP36:%.*]] = load i8***, i8**** [[TMP35]], align 8 -// CHECK3-NEXT: [[TMP37:%.*]] = load i8**, i8*** [[TMP36]], align 8 -// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8 -// CHECK3-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP39]], align 4 -// CHECK3-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP40]] to i64 -// CHECK3-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP37]], i64 [[IDXPROM_I]] -// CHECK3-NEXT: [[TMP41:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8 -// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP43:%.*]] = load i32*, i32** [[TMP42]], align 8 -// CHECK3-NEXT: [[TMP44:%.*]] = load i32, i32* [[TMP43]], align 4 -// CHECK3-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP44]] to i64 -// CHECK3-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP41]], i64 [[IDXPROM4_I]] -// CHECK3-NEXT: [[TMP45:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1 -// CHECK3-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP45]] to i32 -// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK3-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK3-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP47]], [[TMP48]] +// CHECK3-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK3-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META28]]), !noalias !31 +// CHECK3-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META36:![0-9]+]]) +// CHECK3-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META36]]), !noalias !31 +// CHECK3-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META37:![0-9]+]]) +// CHECK3-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META37]]), !noalias !31 +// CHECK3-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META38:![0-9]+]]) +// CHECK3-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META38]]), !noalias !31 +// CHECK3-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META39:![0-9]+]]) +// CHECK3-NEXT: [[TMP31:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP30]], %struct.anon.2** null, i64 0, metadata [[META39]]), !noalias !31 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !31 +// CHECK3-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 +// CHECK3-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: store %struct.anon.2* [[TMP31]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP32:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, i32**)* +// CHECK3-NEXT: call void [[TMP35]](i8* [[TMP34]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2]], !noalias !31 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP32]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP38:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP40:%.*]] = load i32*, i32** [[TMP39]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP40]], align 4, !noalias !31 +// CHECK3-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP43:%.*]] = load i32*, i32** [[TMP42]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP44:%.*]] = load i32, i32* [[TMP43]], align 4, !noalias !31 +// CHECK3-NEXT: store i32 [[TMP44]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 2 +// CHECK3-NEXT: [[TMP46:%.*]] = load i8***, i8**** [[TMP45]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP47:%.*]] = load i8**, i8*** [[TMP46]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP49:%.*]] = load i32*, i32** [[TMP48]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP50:%.*]] = load i32, i32* [[TMP49]], align 4, !noalias !31 +// CHECK3-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP50]] to i64 +// CHECK3-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP47]], i64 [[IDXPROM_I]] +// CHECK3-NEXT: [[TMP51:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP53:%.*]] = load i32*, i32** [[TMP52]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !noalias !31 +// CHECK3-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP54]] to i64 +// CHECK3-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP51]], i64 [[IDXPROM4_I]] +// CHECK3-NEXT: [[TMP55:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1, !noalias !31 +// CHECK3-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP55]] to i32 +// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK3-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK3-NEXT: [[TMP57:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP57]], [[TMP58]] // CHECK3-NEXT: [[SUB9_I:%.*]] = sub i32 [[SUB8_I]], 1 // CHECK3-NEXT: [[CONV11_I:%.*]] = zext i32 [[SUB8_I]] to i64 // CHECK3-NEXT: [[MUL_I:%.*]] = mul nsw i64 [[CONV7_I]], [[CONV11_I]] // CHECK3-NEXT: [[SUB12_I:%.*]] = sub nsw i64 [[MUL_I]], 1 -// CHECK3-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !47 -// CHECK3-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK3-NEXT: store i32 [[TMP49]], i32* [[J_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK3-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP50]] +// CHECK3-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !31 +// CHECK3-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK3-NEXT: store i32 [[TMP59]], i32* [[J_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK3-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP60]] // CHECK3-NEXT: br i1 [[CMP_I]], label [[LAND_LHS_TRUE_I:%.*]], label [[TASKLOOP_IF_END_I:%.*]] // CHECK3: land.lhs.true.i: -// CHECK3-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP51]], [[TMP52]] +// CHECK3-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP61]], [[TMP62]] // CHECK3-NEXT: br i1 [[CMP13_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[TASKLOOP_IF_END_I]] // CHECK3: taskloop.if.then.i: -// CHECK3-NEXT: [[TMP53:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: store i64 [[TMP53]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP55:%.*]] = load i32*, i32** [[TMP54]], align 8 -// CHECK3-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP57:%.*]] = load i8***, i8**** [[TMP56]], align 8 -// CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 3 -// CHECK3-NEXT: [[TMP59:%.*]] = load i8, i8* [[TMP58]], align 1 -// CHECK3-NEXT: [[TOBOOL_I:%.*]] = trunc i8 [[TMP59]] to i1 +// CHECK3-NEXT: [[TMP63:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: store i64 [[TMP63]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP65:%.*]] = load i32*, i32** [[TMP64]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 2 +// CHECK3-NEXT: [[TMP67:%.*]] = load i8***, i8**** [[TMP66]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP68:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 3 +// CHECK3-NEXT: [[TMP69:%.*]] = load i8, i8* [[TMP68]], align 1, !noalias !31 +// CHECK3-NEXT: [[TOBOOL_I:%.*]] = trunc i8 [[TMP69]] to i1 // CHECK3-NEXT: br i1 [[TOBOOL_I]], label [[OMP_IF_THEN_I:%.*]], label [[OMP_IF_ELSE_I:%.*]] // CHECK3: omp_if.then.i: // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK3: omp.inner.for.cond.i: -// CHECK3-NEXT: [[TMP60:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[TMP61:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP60]], [[TMP61]] +// CHECK3-NEXT: [[TMP70:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[TMP71:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP70]], [[TMP71]] // CHECK3-NEXT: br i1 [[CMP16_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK3: omp.inner.for.body.i: -// CHECK3-NEXT: [[TMP62:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[TMP64:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP63]], [[TMP64]] +// CHECK3-NEXT: [[TMP72:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[TMP73:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[TMP74:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP73]], [[TMP74]] // CHECK3-NEXT: [[SUB18_I:%.*]] = sub i32 [[SUB17_I]], 1 // CHECK3-NEXT: [[CONV22_I:%.*]] = zext i32 [[SUB17_I]] to i64 -// CHECK3-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP62]], [[CONV22_I]] +// CHECK3-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP72]], [[CONV22_I]] // CHECK3-NEXT: [[CONV26_I:%.*]] = trunc i64 [[DIV23_I]] to i32 -// CHECK3-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[TMP65:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP65]] to i64 -// CHECK3-NEXT: [[TMP66:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[TMP67:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[TMP68:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[TMP69:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP68]], [[TMP69]] +// CHECK3-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[TMP75:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP75]] to i64 +// CHECK3-NEXT: [[TMP76:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[TMP77:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[TMP78:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[TMP79:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP78]], [[TMP79]] // CHECK3-NEXT: [[SUB29_I:%.*]] = sub i32 [[SUB28_I]], 1 // CHECK3-NEXT: [[CONV33_I:%.*]] = zext i32 [[SUB28_I]] to i64 -// CHECK3-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP67]], [[CONV33_I]] -// CHECK3-NEXT: [[TMP70:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[TMP71:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP70]], [[TMP71]] +// CHECK3-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP77]], [[CONV33_I]] +// CHECK3-NEXT: [[TMP80:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[TMP81:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP80]], [[TMP81]] // CHECK3-NEXT: [[SUB36_I:%.*]] = sub i32 [[SUB35_I]], 1 // CHECK3-NEXT: [[CONV40_I:%.*]] = zext i32 [[SUB35_I]] to i64 // CHECK3-NEXT: [[MUL41_I:%.*]] = mul nsw i64 [[DIV34_I]], [[CONV40_I]] -// CHECK3-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP66]], [[MUL41_I]] +// CHECK3-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP76]], [[MUL41_I]] // CHECK3-NEXT: [[ADD44_I:%.*]] = add nsw i64 [[CONV27_I]], [[SUB42_I]] // CHECK3-NEXT: [[CONV45_I:%.*]] = trunc i64 [[ADD44_I]] to i32 -// CHECK3-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[TMP72:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP72]], 1 -// CHECK3-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK3-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[TMP82:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP82]], 1 +// CHECK3-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP41:![0-9]+]] // CHECK3: omp.inner.for.end.i: // CHECK3-NEXT: br label [[OMP_IF_END_I:%.*]] // CHECK3: omp_if.else.i: // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND47_I:%.*]] // CHECK3: omp.inner.for.cond47.i: -// CHECK3-NEXT: [[TMP73:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP74:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[CMP48_I:%.*]] = icmp ule i64 [[TMP73]], [[TMP74]] +// CHECK3-NEXT: [[TMP83:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP84:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[CMP48_I:%.*]] = icmp ule i64 [[TMP83]], [[TMP84]] // CHECK3-NEXT: br i1 [[CMP48_I]], label [[OMP_INNER_FOR_BODY49_I:%.*]], label [[OMP_INNER_FOR_END82_I:%.*]] // CHECK3: omp.inner.for.body49.i: -// CHECK3-NEXT: [[TMP75:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP76:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP77:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[SUB50_I:%.*]] = sub i32 [[TMP76]], [[TMP77]] +// CHECK3-NEXT: [[TMP85:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP86:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP87:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[SUB50_I:%.*]] = sub i32 [[TMP86]], [[TMP87]] // CHECK3-NEXT: [[SUB51_I:%.*]] = sub i32 [[SUB50_I]], 1 // CHECK3-NEXT: [[CONV55_I:%.*]] = zext i32 [[SUB50_I]] to i64 -// CHECK3-NEXT: [[DIV56_I:%.*]] = sdiv i64 [[TMP75]], [[CONV55_I]] +// CHECK3-NEXT: [[DIV56_I:%.*]] = sdiv i64 [[TMP85]], [[CONV55_I]] // CHECK3-NEXT: [[CONV59_I:%.*]] = trunc i64 [[DIV56_I]] to i32 -// CHECK3-NEXT: store i32 [[CONV59_I]], i32* [[I14_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP78:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[CONV60_I:%.*]] = sext i32 [[TMP78]] to i64 -// CHECK3-NEXT: [[TMP79:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP80:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[TMP81:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP82:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[SUB61_I:%.*]] = sub i32 [[TMP81]], [[TMP82]] +// CHECK3-NEXT: store i32 [[CONV59_I]], i32* [[I14_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP88:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[CONV60_I:%.*]] = sext i32 [[TMP88]] to i64 +// CHECK3-NEXT: [[TMP89:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP90:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[TMP91:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP92:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[SUB61_I:%.*]] = sub i32 [[TMP91]], [[TMP92]] // CHECK3-NEXT: [[SUB62_I:%.*]] = sub i32 [[SUB61_I]], 1 // CHECK3-NEXT: [[CONV66_I:%.*]] = zext i32 [[SUB61_I]] to i64 -// CHECK3-NEXT: [[DIV67_I:%.*]] = sdiv i64 [[TMP80]], [[CONV66_I]] -// CHECK3-NEXT: [[TMP83:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP84:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[SUB68_I:%.*]] = sub i32 [[TMP83]], [[TMP84]] +// CHECK3-NEXT: [[DIV67_I:%.*]] = sdiv i64 [[TMP90]], [[CONV66_I]] +// CHECK3-NEXT: [[TMP93:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP94:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[SUB68_I:%.*]] = sub i32 [[TMP93]], [[TMP94]] // CHECK3-NEXT: [[SUB69_I:%.*]] = sub i32 [[SUB68_I]], 1 // CHECK3-NEXT: [[CONV73_I:%.*]] = zext i32 [[SUB68_I]] to i64 // CHECK3-NEXT: [[MUL74_I:%.*]] = mul nsw i64 [[DIV67_I]], [[CONV73_I]] -// CHECK3-NEXT: [[SUB75_I:%.*]] = sub nsw i64 [[TMP79]], [[MUL74_I]] +// CHECK3-NEXT: [[SUB75_I:%.*]] = sub nsw i64 [[TMP89]], [[MUL74_I]] // CHECK3-NEXT: [[ADD77_I:%.*]] = add nsw i64 [[CONV60_I]], [[SUB75_I]] // CHECK3-NEXT: [[CONV78_I:%.*]] = trunc i64 [[ADD77_I]] to i32 -// CHECK3-NEXT: store i32 [[CONV78_I]], i32* [[J15_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP85:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK3-NEXT: [[ADD81_I:%.*]] = add nsw i64 [[TMP85]], 1 -// CHECK3-NEXT: store i64 [[ADD81_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND47_I]], !llvm.loop [[LOOP51:![0-9]+]] +// CHECK3-NEXT: store i32 [[CONV78_I]], i32* [[J15_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP95:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK3-NEXT: [[ADD81_I:%.*]] = add nsw i64 [[TMP95]], 1 +// CHECK3-NEXT: store i64 [[ADD81_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND47_I]], !llvm.loop [[LOOP43:![0-9]+]] // CHECK3: omp.inner.for.end82.i: // CHECK3-NEXT: br label [[OMP_IF_END_I]] // CHECK3: omp_if.end.i: // CHECK3-NEXT: br label [[TASKLOOP_IF_END_I]] // CHECK3: taskloop.if.end.i: -// CHECK3-NEXT: [[TMP86:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !47 -// CHECK3-NEXT: [[TMP87:%.*]] = icmp ne i32 [[TMP86]], 0 -// CHECK3-NEXT: br i1 [[TMP87]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] +// CHECK3-NEXT: [[TMP96:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 +// CHECK3-NEXT: [[TMP97:%.*]] = icmp ne i32 [[TMP96]], 0 +// CHECK3-NEXT: br i1 [[TMP97]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] // CHECK3: .omp.lastprivate.then.i: // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__6_EXIT]] // CHECK3: .omp_outlined..6.exit: @@ -2575,61 +2598,62 @@ // CHECK3-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK3-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META53:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META62:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !64 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !64 -// CHECK3-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: [[TMP20:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON_4:%.*]], %struct.anon.4* [[TMP20]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP22:%.*]] = load %struct.S*, %struct.S** [[TMP21]], align 8 -// CHECK3-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !64 -// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP20]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP24:%.*]] = load i32*, i32** [[TMP23]], align 8 -// CHECK3-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK3-NEXT: store i32 [[TMP25]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK3-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK3-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP26]], 1 -// CHECK3-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !64 -// CHECK3-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !64 -// CHECK3-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !64 -// CHECK3-NEXT: store i32 0, i32* [[TMP27]], align 4 -// CHECK3-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK3-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP28]] +// CHECK3-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META45:![0-9]+]]) +// CHECK3-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META45]]), !noalias !48 +// CHECK3-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META51:![0-9]+]]) +// CHECK3-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META51]]), !noalias !48 +// CHECK3-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META52:![0-9]+]]) +// CHECK3-NEXT: [[TMP25:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP24]], %struct.anon.4** null, i64 0, metadata [[META52]]), !noalias !48 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !48 +// CHECK3-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !48 +// CHECK3-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store %struct.anon.4* [[TMP25]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: [[TMP26:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_4:%.*]], %struct.anon.4* [[TMP26]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP28:%.*]] = load %struct.S*, %struct.S** [[TMP27]], align 8, !noalias !48 +// CHECK3-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !48 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP26]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8, !noalias !48 +// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4, !noalias !48 +// CHECK3-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !48 +// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !48 +// CHECK3-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP32]], 1 +// CHECK3-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !48 +// CHECK3-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !48 +// CHECK3-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i32 0, i32* [[TMP33]], align 4, !noalias !48 +// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !48 +// CHECK3-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP34]] // CHECK3-NEXT: br i1 [[CMP_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK3: taskloop.if.then.i: -// CHECK3-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !64 -// CHECK3-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !64 -// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP29]] to i32 -// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP20]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 +// CHECK3-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !48 +// CHECK3-NEXT: [[TMP35:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP35]] to i32 +// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !48 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP26]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !48 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK3: omp.inner.for.cond.i: -// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64, !llvm.access.group !65 -// CHECK3-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP32]] to i64 -// CHECK3-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !64, !llvm.access.group !65 -// CHECK3-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP33]] +// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK3-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP38]] to i64 +// CHECK3-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !48, !llvm.access.group !53 +// CHECK3-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP39]] // CHECK3-NEXT: br i1 [[CMP8_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK3: omp.inner.for.body.i: -// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64, !llvm.access.group !65 -// CHECK3-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !64, !llvm.access.group !65 -// CHECK3-NEXT: store i32 [[TMP34]], i32* [[TMP35]], align 4, !llvm.access.group !65 -// CHECK3-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64, !llvm.access.group !65 -// CHECK3-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP36]], 1 -// CHECK3-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !64, !llvm.access.group !65 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP66:![0-9]+]] +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK3-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !48, !llvm.access.group !53 +// CHECK3-NEXT: store i32 [[TMP40]], i32* [[TMP41]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK3-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK3-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP42]], 1 +// CHECK3-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP54:![0-9]+]] // CHECK3: omp.inner.for.end.i: // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT]] // CHECK3: .omp_outlined..9.exit: @@ -2794,40 +2818,41 @@ // CHECK4-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK4-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK4-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK4-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK4-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK4-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK4-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK4-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META9]]), !noalias !6 +// CHECK4-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK4-NEXT: [[TMP25:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP24]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK4-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK4-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store %struct.anon* [[TMP25]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP26:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK4: omp.inner.for.cond.i: -// CHECK4-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK4-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK4-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK4-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK4-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK4-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK4-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK4: omp.inner.for.body.i: -// CHECK4-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK4-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !14 -// CHECK4-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK4-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK4-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK4-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK4-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !6 +// CHECK4-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK4-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK4-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP11:![0-9]+]] // CHECK4: .omp_outlined..1.exit: // CHECK4-NEXT: ret i32 0 // @@ -2910,40 +2935,41 @@ // CHECK4-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK4-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK4-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META27:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META29:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !31 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 -// CHECK4-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: [[TMP20:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: [[TMP21:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 -// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP21]] to i32 -// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK4-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK4-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK4-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META22]]), !noalias !19 +// CHECK4-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK4-NEXT: [[TMP25:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP24]], %struct.anon.0** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: store %struct.anon.0* [[TMP25]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: [[TMP26:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: [[TMP27:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !19 +// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP27]] to i32 +// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !19 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK4: omp.inner.for.cond.i: -// CHECK4-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK4-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP22]] to i64 -// CHECK4-NEXT: [[TMP23:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31, !llvm.access.group !32 -// CHECK4-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP23]] +// CHECK4-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK4-NEXT: [[CONV1_I:%.*]] = sext i32 [[TMP28]] to i64 +// CHECK4-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !19, !llvm.access.group !24 +// CHECK4-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV1_I]], [[TMP29]] // CHECK4-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK4: omp.inner.for.body.i: -// CHECK4-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK4-NEXT: store i32 [[TMP24]], i32* [[I_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK4-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK4-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP25]], 1 -// CHECK4-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !31, !llvm.access.group !32 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK4-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK4-NEXT: store i32 [[TMP30]], i32* [[I_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK4-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK4-NEXT: [[ADD2_I:%.*]] = add nsw i32 [[TMP31]], 1 +// CHECK4-NEXT: store i32 [[ADD2_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !19, !llvm.access.group !24 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP25:![0-9]+]] // CHECK4: .omp_outlined..3.exit: // CHECK4-NEXT: ret i32 0 // @@ -3118,179 +3144,184 @@ // CHECK4-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK4-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK4-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META39:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META41:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META43:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META45:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !47 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !47 -// CHECK4-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP22:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i32**)* -// CHECK4-NEXT: call void [[TMP25]](i8* [[TMP24]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2]] -// CHECK4-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP22]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK4-NEXT: [[TMP28:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8 -// CHECK4-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4 -// CHECK4-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP32]], align 8 -// CHECK4-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP33]], align 4 -// CHECK4-NEXT: store i32 [[TMP34]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP36:%.*]] = load i8***, i8**** [[TMP35]], align 8 -// CHECK4-NEXT: [[TMP37:%.*]] = load i8**, i8*** [[TMP36]], align 8 -// CHECK4-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8 -// CHECK4-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP39]], align 4 -// CHECK4-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP40]] to i64 -// CHECK4-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP37]], i64 [[IDXPROM_I]] -// CHECK4-NEXT: [[TMP41:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8 -// CHECK4-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP43:%.*]] = load i32*, i32** [[TMP42]], align 8 -// CHECK4-NEXT: [[TMP44:%.*]] = load i32, i32* [[TMP43]], align 4 -// CHECK4-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP44]] to i64 -// CHECK4-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP41]], i64 [[IDXPROM4_I]] -// CHECK4-NEXT: [[TMP45:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1 -// CHECK4-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP45]] to i32 -// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK4-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK4-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP47]], [[TMP48]] +// CHECK4-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK4-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META28]]), !noalias !31 +// CHECK4-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META36:![0-9]+]]) +// CHECK4-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META36]]), !noalias !31 +// CHECK4-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META37:![0-9]+]]) +// CHECK4-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META37]]), !noalias !31 +// CHECK4-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META38:![0-9]+]]) +// CHECK4-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META38]]), !noalias !31 +// CHECK4-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META39:![0-9]+]]) +// CHECK4-NEXT: [[TMP31:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP30]], %struct.anon.2** null, i64 0, metadata [[META39]]), !noalias !31 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !31 +// CHECK4-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 +// CHECK4-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: store %struct.anon.2* [[TMP31]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP32:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, i32**)* +// CHECK4-NEXT: call void [[TMP35]](i8* [[TMP34]], i32** [[DOTLASTPRIV_PTR_ADDR_I]]) #[[ATTR2]], !noalias !31 +// CHECK4-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_2:%.*]], %struct.anon.2* [[TMP32]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP38:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP40:%.*]] = load i32*, i32** [[TMP39]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP40]], align 4, !noalias !31 +// CHECK4-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP43:%.*]] = load i32*, i32** [[TMP42]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP44:%.*]] = load i32, i32* [[TMP43]], align 4, !noalias !31 +// CHECK4-NEXT: store i32 [[TMP44]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP45:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 2 +// CHECK4-NEXT: [[TMP46:%.*]] = load i8***, i8**** [[TMP45]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP47:%.*]] = load i8**, i8*** [[TMP46]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP49:%.*]] = load i32*, i32** [[TMP48]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP50:%.*]] = load i32, i32* [[TMP49]], align 4, !noalias !31 +// CHECK4-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP50]] to i64 +// CHECK4-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP47]], i64 [[IDXPROM_I]] +// CHECK4-NEXT: [[TMP51:%.*]] = load i8*, i8** [[ARRAYIDX_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP52:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP53:%.*]] = load i32*, i32** [[TMP52]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP54:%.*]] = load i32, i32* [[TMP53]], align 4, !noalias !31 +// CHECK4-NEXT: [[IDXPROM4_I:%.*]] = sext i32 [[TMP54]] to i64 +// CHECK4-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds i8, i8* [[TMP51]], i64 [[IDXPROM4_I]] +// CHECK4-NEXT: [[TMP55:%.*]] = load i8, i8* [[ARRAYIDX5_I]], align 1, !noalias !31 +// CHECK4-NEXT: [[CONV_I:%.*]] = sext i8 [[TMP55]] to i32 +// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK4-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK4-NEXT: [[TMP57:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[SUB8_I:%.*]] = sub i32 [[TMP57]], [[TMP58]] // CHECK4-NEXT: [[SUB9_I:%.*]] = sub i32 [[SUB8_I]], 1 // CHECK4-NEXT: [[CONV11_I:%.*]] = zext i32 [[SUB8_I]] to i64 // CHECK4-NEXT: [[MUL_I:%.*]] = mul nsw i64 [[CONV7_I]], [[CONV11_I]] // CHECK4-NEXT: [[SUB12_I:%.*]] = sub nsw i64 [[MUL_I]], 1 -// CHECK4-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !47 -// CHECK4-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK4-NEXT: store i32 [[TMP49]], i32* [[J_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !47 -// CHECK4-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP50]] +// CHECK4-NEXT: store i64 [[SUB12_I]], i64* [[DOTCAPTURE_EXPR_6_I]], align 8, !noalias !31 +// CHECK4-NEXT: store i32 0, i32* [[I_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK4-NEXT: store i32 [[TMP59]], i32* [[J_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !31 +// CHECK4-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP60]] // CHECK4-NEXT: br i1 [[CMP_I]], label [[LAND_LHS_TRUE_I:%.*]], label [[TASKLOOP_IF_END_I:%.*]] // CHECK4: land.lhs.true.i: -// CHECK4-NEXT: [[TMP51:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP51]], [[TMP52]] +// CHECK4-NEXT: [[TMP61:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[CMP13_I:%.*]] = icmp slt i32 [[TMP61]], [[TMP62]] // CHECK4-NEXT: br i1 [[CMP13_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[TASKLOOP_IF_END_I]] // CHECK4: taskloop.if.then.i: -// CHECK4-NEXT: [[TMP53:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: store i64 [[TMP53]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP54:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP55:%.*]] = load i32*, i32** [[TMP54]], align 8 -// CHECK4-NEXT: [[TMP56:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP57:%.*]] = load i8***, i8**** [[TMP56]], align 8 -// CHECK4-NEXT: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP22]], i32 0, i32 3 -// CHECK4-NEXT: [[TMP59:%.*]] = load i8, i8* [[TMP58]], align 1 -// CHECK4-NEXT: [[TOBOOL_I:%.*]] = trunc i8 [[TMP59]] to i1 +// CHECK4-NEXT: [[TMP63:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: store i64 [[TMP63]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP64:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP65:%.*]] = load i32*, i32** [[TMP64]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP66:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 2 +// CHECK4-NEXT: [[TMP67:%.*]] = load i8***, i8**** [[TMP66]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP68:%.*]] = getelementptr inbounds [[STRUCT_ANON_2]], %struct.anon.2* [[TMP32]], i32 0, i32 3 +// CHECK4-NEXT: [[TMP69:%.*]] = load i8, i8* [[TMP68]], align 1, !noalias !31 +// CHECK4-NEXT: [[TOBOOL_I:%.*]] = trunc i8 [[TMP69]] to i1 // CHECK4-NEXT: br i1 [[TOBOOL_I]], label [[OMP_IF_THEN_I:%.*]], label [[OMP_IF_ELSE_I:%.*]] // CHECK4: omp_if.then.i: // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK4: omp.inner.for.cond.i: -// CHECK4-NEXT: [[TMP60:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[TMP61:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP60]], [[TMP61]] +// CHECK4-NEXT: [[TMP70:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[TMP71:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[CMP16_I:%.*]] = icmp ule i64 [[TMP70]], [[TMP71]] // CHECK4-NEXT: br i1 [[CMP16_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK4: omp.inner.for.body.i: -// CHECK4-NEXT: [[TMP62:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[TMP64:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP63]], [[TMP64]] +// CHECK4-NEXT: [[TMP72:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[TMP73:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[TMP74:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[SUB17_I:%.*]] = sub i32 [[TMP73]], [[TMP74]] // CHECK4-NEXT: [[SUB18_I:%.*]] = sub i32 [[SUB17_I]], 1 // CHECK4-NEXT: [[CONV22_I:%.*]] = zext i32 [[SUB17_I]] to i64 -// CHECK4-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP62]], [[CONV22_I]] +// CHECK4-NEXT: [[DIV23_I:%.*]] = sdiv i64 [[TMP72]], [[CONV22_I]] // CHECK4-NEXT: [[CONV26_I:%.*]] = trunc i64 [[DIV23_I]] to i32 -// CHECK4-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[TMP65:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP65]] to i64 -// CHECK4-NEXT: [[TMP66:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[TMP67:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[TMP68:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[TMP69:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP68]], [[TMP69]] +// CHECK4-NEXT: store i32 [[CONV26_I]], i32* [[I14_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[TMP75:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[CONV27_I:%.*]] = sext i32 [[TMP75]] to i64 +// CHECK4-NEXT: [[TMP76:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[TMP77:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[TMP78:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[TMP79:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[SUB28_I:%.*]] = sub i32 [[TMP78]], [[TMP79]] // CHECK4-NEXT: [[SUB29_I:%.*]] = sub i32 [[SUB28_I]], 1 // CHECK4-NEXT: [[CONV33_I:%.*]] = zext i32 [[SUB28_I]] to i64 -// CHECK4-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP67]], [[CONV33_I]] -// CHECK4-NEXT: [[TMP70:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[TMP71:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP70]], [[TMP71]] +// CHECK4-NEXT: [[DIV34_I:%.*]] = sdiv i64 [[TMP77]], [[CONV33_I]] +// CHECK4-NEXT: [[TMP80:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[TMP81:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[SUB35_I:%.*]] = sub i32 [[TMP80]], [[TMP81]] // CHECK4-NEXT: [[SUB36_I:%.*]] = sub i32 [[SUB35_I]], 1 // CHECK4-NEXT: [[CONV40_I:%.*]] = zext i32 [[SUB35_I]] to i64 // CHECK4-NEXT: [[MUL41_I:%.*]] = mul nsw i64 [[DIV34_I]], [[CONV40_I]] -// CHECK4-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP66]], [[MUL41_I]] +// CHECK4-NEXT: [[SUB42_I:%.*]] = sub nsw i64 [[TMP76]], [[MUL41_I]] // CHECK4-NEXT: [[ADD44_I:%.*]] = add nsw i64 [[CONV27_I]], [[SUB42_I]] // CHECK4-NEXT: [[CONV45_I:%.*]] = trunc i64 [[ADD44_I]] to i32 -// CHECK4-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[TMP72:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP72]], 1 -// CHECK4-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47, !llvm.access.group !48 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK4-NEXT: store i32 [[CONV45_I]], i32* [[J15_I]], align 4, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[TMP82:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: [[ADD46_I:%.*]] = add nsw i64 [[TMP82]], 1 +// CHECK4-NEXT: store i64 [[ADD46_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31, !llvm.access.group !40 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP41:![0-9]+]] // CHECK4: omp.inner.for.end.i: // CHECK4-NEXT: br label [[OMP_IF_END_I:%.*]] // CHECK4: omp_if.else.i: // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND47_I:%.*]] // CHECK4: omp.inner.for.cond47.i: -// CHECK4-NEXT: [[TMP73:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP74:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[CMP48_I:%.*]] = icmp ule i64 [[TMP73]], [[TMP74]] +// CHECK4-NEXT: [[TMP83:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP84:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[CMP48_I:%.*]] = icmp ule i64 [[TMP83]], [[TMP84]] // CHECK4-NEXT: br i1 [[CMP48_I]], label [[OMP_INNER_FOR_BODY49_I:%.*]], label [[OMP_INNER_FOR_END82_I:%.*]] // CHECK4: omp.inner.for.body49.i: -// CHECK4-NEXT: [[TMP75:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP76:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP77:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[SUB50_I:%.*]] = sub i32 [[TMP76]], [[TMP77]] +// CHECK4-NEXT: [[TMP85:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP86:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP87:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[SUB50_I:%.*]] = sub i32 [[TMP86]], [[TMP87]] // CHECK4-NEXT: [[SUB51_I:%.*]] = sub i32 [[SUB50_I]], 1 // CHECK4-NEXT: [[CONV55_I:%.*]] = zext i32 [[SUB50_I]] to i64 -// CHECK4-NEXT: [[DIV56_I:%.*]] = sdiv i64 [[TMP75]], [[CONV55_I]] +// CHECK4-NEXT: [[DIV56_I:%.*]] = sdiv i64 [[TMP85]], [[CONV55_I]] // CHECK4-NEXT: [[CONV59_I:%.*]] = trunc i64 [[DIV56_I]] to i32 -// CHECK4-NEXT: store i32 [[CONV59_I]], i32* [[I14_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP78:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[CONV60_I:%.*]] = sext i32 [[TMP78]] to i64 -// CHECK4-NEXT: [[TMP79:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP80:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[TMP81:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP82:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[SUB61_I:%.*]] = sub i32 [[TMP81]], [[TMP82]] +// CHECK4-NEXT: store i32 [[CONV59_I]], i32* [[I14_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP88:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[CONV60_I:%.*]] = sext i32 [[TMP88]] to i64 +// CHECK4-NEXT: [[TMP89:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP90:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[TMP91:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP92:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[SUB61_I:%.*]] = sub i32 [[TMP91]], [[TMP92]] // CHECK4-NEXT: [[SUB62_I:%.*]] = sub i32 [[SUB61_I]], 1 // CHECK4-NEXT: [[CONV66_I:%.*]] = zext i32 [[SUB61_I]] to i64 -// CHECK4-NEXT: [[DIV67_I:%.*]] = sdiv i64 [[TMP80]], [[CONV66_I]] -// CHECK4-NEXT: [[TMP83:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP84:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[SUB68_I:%.*]] = sub i32 [[TMP83]], [[TMP84]] +// CHECK4-NEXT: [[DIV67_I:%.*]] = sdiv i64 [[TMP90]], [[CONV66_I]] +// CHECK4-NEXT: [[TMP93:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_3_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP94:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[SUB68_I:%.*]] = sub i32 [[TMP93]], [[TMP94]] // CHECK4-NEXT: [[SUB69_I:%.*]] = sub i32 [[SUB68_I]], 1 // CHECK4-NEXT: [[CONV73_I:%.*]] = zext i32 [[SUB68_I]] to i64 // CHECK4-NEXT: [[MUL74_I:%.*]] = mul nsw i64 [[DIV67_I]], [[CONV73_I]] -// CHECK4-NEXT: [[SUB75_I:%.*]] = sub nsw i64 [[TMP79]], [[MUL74_I]] +// CHECK4-NEXT: [[SUB75_I:%.*]] = sub nsw i64 [[TMP89]], [[MUL74_I]] // CHECK4-NEXT: [[ADD77_I:%.*]] = add nsw i64 [[CONV60_I]], [[SUB75_I]] // CHECK4-NEXT: [[CONV78_I:%.*]] = trunc i64 [[ADD77_I]] to i32 -// CHECK4-NEXT: store i32 [[CONV78_I]], i32* [[J15_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP85:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK4-NEXT: [[ADD81_I:%.*]] = add nsw i64 [[TMP85]], 1 -// CHECK4-NEXT: store i64 [[ADD81_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !47 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND47_I]], !llvm.loop [[LOOP51:![0-9]+]] +// CHECK4-NEXT: store i32 [[CONV78_I]], i32* [[J15_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP95:%.*]] = load i64, i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK4-NEXT: [[ADD81_I:%.*]] = add nsw i64 [[TMP95]], 1 +// CHECK4-NEXT: store i64 [[ADD81_I]], i64* [[DOTOMP_IV_I]], align 8, !noalias !31 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND47_I]], !llvm.loop [[LOOP43:![0-9]+]] // CHECK4: omp.inner.for.end82.i: // CHECK4-NEXT: br label [[OMP_IF_END_I]] // CHECK4: omp_if.end.i: // CHECK4-NEXT: br label [[TASKLOOP_IF_END_I]] // CHECK4: taskloop.if.end.i: -// CHECK4-NEXT: [[TMP86:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !47 -// CHECK4-NEXT: [[TMP87:%.*]] = icmp ne i32 [[TMP86]], 0 -// CHECK4-NEXT: br i1 [[TMP87]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] +// CHECK4-NEXT: [[TMP96:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !31 +// CHECK4-NEXT: [[TMP97:%.*]] = icmp ne i32 [[TMP96]], 0 +// CHECK4-NEXT: br i1 [[TMP97]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__6_EXIT:%.*]] // CHECK4: .omp.lastprivate.then.i: // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__6_EXIT]] // CHECK4: .omp_outlined..6.exit: @@ -3475,61 +3506,62 @@ // CHECK4-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK4-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK4-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META53:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META62:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !64 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !64 -// CHECK4-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: [[TMP20:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON_4:%.*]], %struct.anon.4* [[TMP20]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP22:%.*]] = load %struct.S*, %struct.S** [[TMP21]], align 8 -// CHECK4-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !64 -// CHECK4-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP20]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP24:%.*]] = load i32*, i32** [[TMP23]], align 8 -// CHECK4-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK4-NEXT: store i32 [[TMP25]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK4-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK4-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP26]], 1 -// CHECK4-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !64 -// CHECK4-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !64 -// CHECK4-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !64 -// CHECK4-NEXT: store i32 0, i32* [[TMP27]], align 4 -// CHECK4-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !64 -// CHECK4-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP28]] +// CHECK4-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META45:![0-9]+]]) +// CHECK4-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META45]]), !noalias !48 +// CHECK4-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META51:![0-9]+]]) +// CHECK4-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META51]]), !noalias !48 +// CHECK4-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META52:![0-9]+]]) +// CHECK4-NEXT: [[TMP25:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP24]], %struct.anon.4** null, i64 0, metadata [[META52]]), !noalias !48 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !48 +// CHECK4-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !48 +// CHECK4-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store %struct.anon.4* [[TMP25]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: [[TMP26:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON_4:%.*]], %struct.anon.4* [[TMP26]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP28:%.*]] = load %struct.S*, %struct.S** [[TMP27]], align 8, !noalias !48 +// CHECK4-NEXT: store i32* [[TMP_I]], i32** [[TMP1_I]], align 8, !noalias !48 +// CHECK4-NEXT: [[TMP29:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP26]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP30:%.*]] = load i32*, i32** [[TMP29]], align 8, !noalias !48 +// CHECK4-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP30]], align 4, !noalias !48 +// CHECK4-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !48 +// CHECK4-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !48 +// CHECK4-NEXT: [[SUB3_I:%.*]] = sub nsw i32 [[TMP32]], 1 +// CHECK4-NEXT: store i32 [[SUB3_I]], i32* [[DOTCAPTURE_EXPR_2_I]], align 4, !noalias !48 +// CHECK4-NEXT: store i32* [[A_I]], i32** [[TMP4_I]], align 8, !noalias !48 +// CHECK4-NEXT: [[TMP33:%.*]] = load i32*, i32** [[TMP4_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i32 0, i32* [[TMP33]], align 4, !noalias !48 +// CHECK4-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__I]], align 4, !noalias !48 +// CHECK4-NEXT: [[CMP_I:%.*]] = icmp slt i32 0, [[TMP34]] // CHECK4-NEXT: br i1 [[CMP_I]], label [[TASKLOOP_IF_THEN_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK4: taskloop.if.then.i: -// CHECK4-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !64 -// CHECK4-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !64 -// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP29]] to i32 -// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !64 -// CHECK4-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP20]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 +// CHECK4-NEXT: store i32* [[A5_I]], i32** [[TMP6_I]], align 8, !noalias !48 +// CHECK4-NEXT: [[TMP35:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP35]] to i32 +// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !48 +// CHECK4-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_4]], %struct.anon.4* [[TMP26]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !48 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK4: omp.inner.for.cond.i: -// CHECK4-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64, !llvm.access.group !65 -// CHECK4-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP32]] to i64 -// CHECK4-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !64, !llvm.access.group !65 -// CHECK4-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP33]] +// CHECK4-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK4-NEXT: [[CONV7_I:%.*]] = sext i32 [[TMP38]] to i64 +// CHECK4-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !48, !llvm.access.group !53 +// CHECK4-NEXT: [[CMP8_I:%.*]] = icmp ule i64 [[CONV7_I]], [[TMP39]] // CHECK4-NEXT: br i1 [[CMP8_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK4: omp.inner.for.body.i: -// CHECK4-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64, !llvm.access.group !65 -// CHECK4-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !64, !llvm.access.group !65 -// CHECK4-NEXT: store i32 [[TMP34]], i32* [[TMP35]], align 4, !llvm.access.group !65 -// CHECK4-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !64, !llvm.access.group !65 -// CHECK4-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP36]], 1 -// CHECK4-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !64, !llvm.access.group !65 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP66:![0-9]+]] +// CHECK4-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK4-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP6_I]], align 8, !noalias !48, !llvm.access.group !53 +// CHECK4-NEXT: store i32 [[TMP40]], i32* [[TMP41]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK4-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK4-NEXT: [[ADD9_I:%.*]] = add nsw i32 [[TMP42]], 1 +// CHECK4-NEXT: store i32 [[ADD9_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !48, !llvm.access.group !53 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP54:![0-9]+]] // CHECK4: omp.inner.for.end.i: // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__9_EXIT]] // CHECK4: .omp_outlined..9.exit: Index: clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp +++ clang/test/OpenMP/parallel_master_taskloop_simd_firstprivate_codegen.cpp @@ -284,7 +284,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -424,7 +425,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp +++ clang/test/OpenMP/parallel_master_taskloop_simd_lastprivate_codegen.cpp @@ -420,101 +420,106 @@ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* -// CHECK1-NEXT: call void [[TMP25]](i8* [[TMP24]], %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], i32** [[DOTLASTPRIV_PTR_ADDR4_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 3 -// CHECK1-NEXT: [[TMP27:%.*]] = load %struct.S*, %struct.S** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP30]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP33:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP32]], align 8 -// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP35:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP34]], align 8 -// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 3 -// CHECK1-NEXT: [[TMP37:%.*]] = load %struct.S*, %struct.S** [[TMP36]], align 8 -// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 4 -// CHECK1-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = load %struct.S*, %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP42:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP43:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP44:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR4_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK1-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK1-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* +// CHECK1-NEXT: call void [[TMP35]](i8* [[TMP34]], %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], i32** [[DOTLASTPRIV_PTR_ADDR4_I]]) #[[ATTR4]], !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 3 +// CHECK1-NEXT: [[TMP37:%.*]] = load %struct.S*, %struct.S** [[TMP36]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP41:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP40]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP43:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP42]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP45:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP44]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 3 +// CHECK1-NEXT: [[TMP47:%.*]] = load %struct.S*, %struct.S** [[TMP46]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 4 +// CHECK1-NEXT: [[TMP49:%.*]] = load i32*, i32** [[TMP48]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP50:%.*]] = load %struct.S*, %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP53:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP54:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR4_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK1-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV5_I]], [[TMP47]] +// CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK1-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV5_I]], [[TMP57]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[TMP41]], align 4, !llvm.access.group !15 -// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP43]], i64 0, i64 0 -// CHECK1-NEXT: store i32 [[TMP49]], i32* [[ARRAYIDX_I]], align 4, !llvm.access.group !15 -// CHECK1-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP42]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP50:%.*]] = bitcast %struct.S* [[ARRAYIDX6_I]] to i8* -// CHECK1-NEXT: [[TMP51:%.*]] = bitcast %struct.S* [[TMP40]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP50]], i8* align 8 [[TMP51]], i64 8, i1 false) #[[ATTR4]], !llvm.access.group !15 -// CHECK1-NEXT: store i32 33, i32* [[TMP44]], align 4, !llvm.access.group !15 -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[TMP51]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP53]], i64 0, i64 0 +// CHECK1-NEXT: store i32 [[TMP59]], i32* [[ARRAYIDX_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP52]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP60:%.*]] = bitcast %struct.S* [[ARRAYIDX6_I]] to i8* +// CHECK1-NEXT: [[TMP61:%.*]] = bitcast %struct.S* [[TMP50]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP60]], i8* align 8 [[TMP61]], i64 8, i1 false) #[[ATTR4]], !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: store i32 33, i32* [[TMP54]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK1: omp.inner.for.end.i: -// CHECK1-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP54:%.*]] = icmp ne i32 [[TMP53]], 0 -// CHECK1-NEXT: br i1 [[TMP54]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK1-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP64:%.*]] = icmp ne i32 [[TMP63]], 0 +// CHECK1-NEXT: br i1 [[TMP64]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: .omp.lastprivate.then.i: -// CHECK1-NEXT: [[TMP55:%.*]] = bitcast %struct.S* [[TMP27]] to i8* -// CHECK1-NEXT: [[TMP56:%.*]] = bitcast %struct.S* [[TMP40]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP55]], i8* align 8 [[TMP56]], i64 8, i1 false) #[[ATTR4]] -// CHECK1-NEXT: [[TMP57:%.*]] = load i32, i32* [[TMP41]], align 4 -// CHECK1-NEXT: store i32 [[TMP57]], i32* [[TMP29]], align 4 -// CHECK1-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP31]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP58:%.*]] = bitcast [2 x %struct.S]* [[TMP42]] to %struct.S* -// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[ARRAY_BEGIN_I]], i64 2 +// CHECK1-NEXT: [[TMP65:%.*]] = bitcast %struct.S* [[TMP37]] to i8* +// CHECK1-NEXT: [[TMP66:%.*]] = bitcast %struct.S* [[TMP50]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP65]], i8* align 8 [[TMP66]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK1-NEXT: [[TMP67:%.*]] = load i32, i32* [[TMP51]], align 4, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP67]], i32* [[TMP39]], align 4, !noalias !6 +// CHECK1-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP41]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP68:%.*]] = bitcast [2 x %struct.S]* [[TMP52]] to %struct.S* +// CHECK1-NEXT: [[TMP69:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[ARRAY_BEGIN_I]], i64 2 // CHECK1-NEXT: br label [[OMP_ARRAYCPY_BODY_I:%.*]] // CHECK1: omp.arraycpy.body.i: -// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S* [ [[TMP58]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] +// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S* [ [[TMP68]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST_I:%.*]] = phi %struct.S* [ [[ARRAY_BEGIN_I]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] -// CHECK1-NEXT: [[TMP60:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* -// CHECK1-NEXT: [[TMP61:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP60]], i8* align 8 [[TMP61]], i64 8, i1 false) #[[ATTR4]] +// CHECK1-NEXT: [[TMP70:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* +// CHECK1-NEXT: [[TMP71:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP70]], i8* align 8 [[TMP71]], i64 8, i1 false) #[[ATTR4]], !noalias !6 // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT_I]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]], i32 1 // CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT_I]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]], i32 1 -// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP59]] +// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP69]] // CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE_I]], label [[OMP_ARRAYCPY_DONE8_I:%.*]], label [[OMP_ARRAYCPY_BODY_I]] // CHECK1: omp.arraycpy.done8.i: -// CHECK1-NEXT: [[TMP62:%.*]] = bitcast [2 x i32]* [[TMP33]] to i8* -// CHECK1-NEXT: [[TMP63:%.*]] = bitcast [2 x i32]* [[TMP43]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP62]], i8* align 4 [[TMP63]], i64 8, i1 false) #[[ATTR4]] -// CHECK1-NEXT: [[TMP64:%.*]] = load i32, i32* [[TMP44]], align 4 -// CHECK1-NEXT: store i32 [[TMP64]], i32* [[TMP39]], align 4 +// CHECK1-NEXT: [[TMP72:%.*]] = bitcast [2 x i32]* [[TMP43]] to i8* +// CHECK1-NEXT: [[TMP73:%.*]] = bitcast [2 x i32]* [[TMP53]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP72]], i8* align 4 [[TMP73]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK1-NEXT: [[TMP74:%.*]] = load i32, i32* [[TMP54]], align 4, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP74]], i32* [[TMP49]], align 4, !noalias !6 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .omp_outlined..1.exit: // CHECK1-NEXT: ret i32 0 @@ -835,95 +840,100 @@ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 64 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.3*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* @.omp_task_privates_map..4 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !32 -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store %struct.anon.1* [[TMP8]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* -// CHECK1-NEXT: call void [[TMP25]](i8* [[TMP24]], i32** [[DOTLASTPRIV_PTR_ADDR_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP29:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP28]], align 8 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP30]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP33:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP32]], align 8 -// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 3 -// CHECK1-NEXT: [[TMP35:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP34]], align 8 -// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 3 -// CHECK1-NEXT: [[TMP37:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP36]], align 8 -// CHECK1-NEXT: [[TMP38:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP39:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP40:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP41:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP42]] to i32 -// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !32 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META21]]), !noalias !24 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META29:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META29]]), !noalias !24 +// CHECK1-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META30:![0-9]+]]) +// CHECK1-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.3*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* @.omp_task_privates_map..4 to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META30]]), !noalias !24 +// CHECK1-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META31:![0-9]+]]) +// CHECK1-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META31]]), !noalias !24 +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1** null, i64 0, metadata [[META32:![0-9]+]]) +// CHECK1-NEXT: [[TMP31:%.*]] = call %struct.anon.1* @llvm.noalias.p0s_struct.anon.1s.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1* [[TMP8]], i8* [[TMP30]], %struct.anon.1** null, i64 0, metadata [[META32]]), !noalias !24 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK1-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !24 +// CHECK1-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store %struct.anon.1* [[TMP31]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP32:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* +// CHECK1-NEXT: call void [[TMP35]](i8* [[TMP34]], i32** [[DOTLASTPRIV_PTR_ADDR_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !24 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP39:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP38]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP41:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP40]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP43:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP42]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 3 +// CHECK1-NEXT: [[TMP45:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP44]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 3 +// CHECK1-NEXT: [[TMP47:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP46]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP48:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP49:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP50:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP51:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP52:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP52]] to i32 +// CHECK1-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !24 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32, !llvm.access.group !33 -// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !32, !llvm.access.group !33 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP44]] +// CHECK1-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP53]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !24, !llvm.access.group !33 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP54]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32, !llvm.access.group !33 -// CHECK1-NEXT: store i32 [[TMP45]], i32* [[I_I]], align 4, !noalias !32, !llvm.access.group !33 -// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[TMP38]], align 128, !llvm.access.group !33 -// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP39]], i64 0, i64 0 -// CHECK1-NEXT: store i32 [[TMP46]], i32* [[ARRAYIDX_I]], align 4, !llvm.access.group !33 -// CHECK1-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP40]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP47:%.*]] = bitcast %struct.S.0* [[ARRAYIDX5_I]] to i8* -// CHECK1-NEXT: [[TMP48:%.*]] = bitcast %struct.S.0* [[TMP41]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP47]], i8* align 4 [[TMP48]], i64 4, i1 false) #[[ATTR4]], !llvm.access.group !33 -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32, !llvm.access.group !33 -// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP49]], 1 -// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !32, !llvm.access.group !33 +// CHECK1-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK1-NEXT: store i32 [[TMP55]], i32* [[I_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP48]], align 128, !noalias !24, !llvm.access.group !33 +// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP49]], i64 0, i64 0 +// CHECK1-NEXT: store i32 [[TMP56]], i32* [[ARRAYIDX_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK1-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP50]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP57:%.*]] = bitcast %struct.S.0* [[ARRAYIDX5_I]] to i8* +// CHECK1-NEXT: [[TMP58:%.*]] = bitcast %struct.S.0* [[TMP51]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP57]], i8* align 4 [[TMP58]], i64 4, i1 false) #[[ATTR4]], !noalias !24, !llvm.access.group !33 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP59]], 1 +// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !24, !llvm.access.group !33 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP34:![0-9]+]] // CHECK1: omp.inner.for.end.i: -// CHECK1-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !32 -// CHECK1-NEXT: [[TMP51:%.*]] = icmp ne i32 [[TMP50]], 0 -// CHECK1-NEXT: br i1 [[TMP51]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK1-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP61:%.*]] = icmp ne i32 [[TMP60]], 0 +// CHECK1-NEXT: br i1 [[TMP61]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK1: .omp.lastprivate.then.i: -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[TMP38]], align 128 -// CHECK1-NEXT: store i32 [[TMP52]], i32* [[TMP27]], align 128 -// CHECK1-NEXT: [[TMP53:%.*]] = bitcast [2 x i32]* [[TMP29]] to i8* -// CHECK1-NEXT: [[TMP54:%.*]] = bitcast [2 x i32]* [[TMP39]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP53]], i8* align 4 [[TMP54]], i64 8, i1 false) #[[ATTR4]] -// CHECK1-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP31]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP55:%.*]] = bitcast [2 x %struct.S.0]* [[TMP40]] to %struct.S.0* -// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN_I]], i64 2 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[TMP48]], align 128, !noalias !24 +// CHECK1-NEXT: store i32 [[TMP62]], i32* [[TMP37]], align 128, !noalias !24 +// CHECK1-NEXT: [[TMP63:%.*]] = bitcast [2 x i32]* [[TMP39]] to i8* +// CHECK1-NEXT: [[TMP64:%.*]] = bitcast [2 x i32]* [[TMP49]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP63]], i8* align 4 [[TMP64]], i64 8, i1 false) #[[ATTR4]], !noalias !24 +// CHECK1-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP41]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP65:%.*]] = bitcast [2 x %struct.S.0]* [[TMP50]] to %struct.S.0* +// CHECK1-NEXT: [[TMP66:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN_I]], i64 2 // CHECK1-NEXT: br label [[OMP_ARRAYCPY_BODY_I:%.*]] // CHECK1: omp.arraycpy.body.i: -// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[TMP55]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] +// CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[TMP65]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN_I]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] -// CHECK1-NEXT: [[TMP57:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* -// CHECK1-NEXT: [[TMP58:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP57]], i8* align 4 [[TMP58]], i64 4, i1 false) #[[ATTR4]] +// CHECK1-NEXT: [[TMP67:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* +// CHECK1-NEXT: [[TMP68:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP67]], i8* align 4 [[TMP68]], i64 4, i1 false) #[[ATTR4]], !noalias !24 // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT_I]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]], i32 1 // CHECK1-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT_I]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]], i32 1 -// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP56]] +// CHECK1-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP66]] // CHECK1-NEXT: br i1 [[OMP_ARRAYCPY_DONE_I]], label [[OMP_ARRAYCPY_DONE7_I:%.*]], label [[OMP_ARRAYCPY_BODY_I]] // CHECK1: omp.arraycpy.done7.i: -// CHECK1-NEXT: [[TMP59:%.*]] = bitcast %struct.S.0* [[TMP35]] to i8* -// CHECK1-NEXT: [[TMP60:%.*]] = bitcast %struct.S.0* [[TMP41]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP59]], i8* align 4 [[TMP60]], i64 4, i1 false) #[[ATTR4]] +// CHECK1-NEXT: [[TMP69:%.*]] = bitcast %struct.S.0* [[TMP45]] to i8* +// CHECK1-NEXT: [[TMP70:%.*]] = bitcast %struct.S.0* [[TMP51]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP69]], i8* align 4 [[TMP70]], i64 4, i1 false) #[[ATTR4]], !noalias !24 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK1: .omp_outlined..3.exit: // CHECK1-NEXT: ret i32 0 @@ -1254,101 +1264,106 @@ // CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* -// CHECK2-NEXT: call void [[TMP25]](i8* [[TMP24]], %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], i32** [[DOTLASTPRIV_PTR_ADDR4_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 3 -// CHECK2-NEXT: [[TMP27:%.*]] = load %struct.S*, %struct.S** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP30]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP33:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP32]], align 8 -// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP35:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP34]], align 8 -// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 3 -// CHECK2-NEXT: [[TMP37:%.*]] = load %struct.S*, %struct.S** [[TMP36]], align 8 -// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 4 -// CHECK2-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = load %struct.S*, %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP42:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP43:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP44:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR4_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK2-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK2-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, %struct.S**, i32**, [2 x %struct.S]**, [2 x i32]**, i32**)* +// CHECK2-NEXT: call void [[TMP35]](i8* [[TMP34]], %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], i32** [[DOTLASTPRIV_PTR_ADDR4_I]]) #[[ATTR4]], !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 3 +// CHECK2-NEXT: [[TMP37:%.*]] = load %struct.S*, %struct.S** [[TMP36]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP41:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP40]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP43:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP42]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP45:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP44]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 3 +// CHECK2-NEXT: [[TMP47:%.*]] = load %struct.S*, %struct.S** [[TMP46]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 4 +// CHECK2-NEXT: [[TMP49:%.*]] = load i32*, i32** [[TMP48]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP50:%.*]] = load %struct.S*, %struct.S** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP53:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP54:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR4_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK2-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV5_I]], [[TMP47]] +// CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK2-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV5_I]], [[TMP57]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[TMP41]], align 4, !llvm.access.group !15 -// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP43]], i64 0, i64 0 -// CHECK2-NEXT: store i32 [[TMP49]], i32* [[ARRAYIDX_I]], align 4, !llvm.access.group !15 -// CHECK2-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP42]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP50:%.*]] = bitcast %struct.S* [[ARRAYIDX6_I]] to i8* -// CHECK2-NEXT: [[TMP51:%.*]] = bitcast %struct.S* [[TMP40]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP50]], i8* align 8 [[TMP51]], i64 8, i1 false) #[[ATTR4]], !llvm.access.group !15 -// CHECK2-NEXT: store i32 33, i32* [[TMP44]], align 4, !llvm.access.group !15 -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[TMP51]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP53]], i64 0, i64 0 +// CHECK2-NEXT: store i32 [[TMP59]], i32* [[ARRAYIDX_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[ARRAYIDX6_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP52]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP60:%.*]] = bitcast %struct.S* [[ARRAYIDX6_I]] to i8* +// CHECK2-NEXT: [[TMP61:%.*]] = bitcast %struct.S* [[TMP50]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP60]], i8* align 8 [[TMP61]], i64 8, i1 false) #[[ATTR4]], !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: store i32 33, i32* [[TMP54]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK2: omp.inner.for.end.i: -// CHECK2-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP54:%.*]] = icmp ne i32 [[TMP53]], 0 -// CHECK2-NEXT: br i1 [[TMP54]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK2-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP64:%.*]] = icmp ne i32 [[TMP63]], 0 +// CHECK2-NEXT: br i1 [[TMP64]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: .omp.lastprivate.then.i: -// CHECK2-NEXT: [[TMP55:%.*]] = bitcast %struct.S* [[TMP27]] to i8* -// CHECK2-NEXT: [[TMP56:%.*]] = bitcast %struct.S* [[TMP40]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP55]], i8* align 8 [[TMP56]], i64 8, i1 false) #[[ATTR4]] -// CHECK2-NEXT: [[TMP57:%.*]] = load i32, i32* [[TMP41]], align 4 -// CHECK2-NEXT: store i32 [[TMP57]], i32* [[TMP29]], align 4 -// CHECK2-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP31]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP58:%.*]] = bitcast [2 x %struct.S]* [[TMP42]] to %struct.S* -// CHECK2-NEXT: [[TMP59:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[ARRAY_BEGIN_I]], i64 2 +// CHECK2-NEXT: [[TMP65:%.*]] = bitcast %struct.S* [[TMP37]] to i8* +// CHECK2-NEXT: [[TMP66:%.*]] = bitcast %struct.S* [[TMP50]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP65]], i8* align 8 [[TMP66]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK2-NEXT: [[TMP67:%.*]] = load i32, i32* [[TMP51]], align 4, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP67]], i32* [[TMP39]], align 4, !noalias !6 +// CHECK2-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP41]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP68:%.*]] = bitcast [2 x %struct.S]* [[TMP52]] to %struct.S* +// CHECK2-NEXT: [[TMP69:%.*]] = getelementptr [[STRUCT_S:%.*]], %struct.S* [[ARRAY_BEGIN_I]], i64 2 // CHECK2-NEXT: br label [[OMP_ARRAYCPY_BODY_I:%.*]] // CHECK2: omp.arraycpy.body.i: -// CHECK2-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S* [ [[TMP58]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] +// CHECK2-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S* [ [[TMP68]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] // CHECK2-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST_I:%.*]] = phi %struct.S* [ [[ARRAY_BEGIN_I]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] -// CHECK2-NEXT: [[TMP60:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* -// CHECK2-NEXT: [[TMP61:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP60]], i8* align 8 [[TMP61]], i64 8, i1 false) #[[ATTR4]] +// CHECK2-NEXT: [[TMP70:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* +// CHECK2-NEXT: [[TMP71:%.*]] = bitcast %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[TMP70]], i8* align 8 [[TMP71]], i64 8, i1 false) #[[ATTR4]], !noalias !6 // CHECK2-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT_I]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]], i32 1 // CHECK2-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT_I]] = getelementptr [[STRUCT_S]], %struct.S* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]], i32 1 -// CHECK2-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP59]] +// CHECK2-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP69]] // CHECK2-NEXT: br i1 [[OMP_ARRAYCPY_DONE_I]], label [[OMP_ARRAYCPY_DONE8_I:%.*]], label [[OMP_ARRAYCPY_BODY_I]] // CHECK2: omp.arraycpy.done8.i: -// CHECK2-NEXT: [[TMP62:%.*]] = bitcast [2 x i32]* [[TMP33]] to i8* -// CHECK2-NEXT: [[TMP63:%.*]] = bitcast [2 x i32]* [[TMP43]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP62]], i8* align 4 [[TMP63]], i64 8, i1 false) #[[ATTR4]] -// CHECK2-NEXT: [[TMP64:%.*]] = load i32, i32* [[TMP44]], align 4 -// CHECK2-NEXT: store i32 [[TMP64]], i32* [[TMP39]], align 4 +// CHECK2-NEXT: [[TMP72:%.*]] = bitcast [2 x i32]* [[TMP43]] to i8* +// CHECK2-NEXT: [[TMP73:%.*]] = bitcast [2 x i32]* [[TMP53]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP72]], i8* align 4 [[TMP73]], i64 8, i1 false) #[[ATTR4]], !noalias !6 +// CHECK2-NEXT: [[TMP74:%.*]] = load i32, i32* [[TMP54]], align 4, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP74]], i32* [[TMP49]], align 4, !noalias !6 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .omp_outlined..1.exit: // CHECK2-NEXT: ret i32 0 @@ -1669,95 +1684,100 @@ // CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 64 // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.3*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* @.omp_task_privates_map..4 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !32 -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store %struct.anon.1* [[TMP8]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* -// CHECK2-NEXT: call void [[TMP25]](i8* [[TMP24]], i32** [[DOTLASTPRIV_PTR_ADDR_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP29:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP28]], align 8 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP30]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP33:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP32]], align 8 -// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 3 -// CHECK2-NEXT: [[TMP35:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP34]], align 8 -// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP22]], i32 0, i32 3 -// CHECK2-NEXT: [[TMP37:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP36]], align 8 -// CHECK2-NEXT: [[TMP38:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP39:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP40:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP41:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP42]] to i32 -// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !32 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META21]]), !noalias !24 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META29:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META29]]), !noalias !24 +// CHECK2-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META30:![0-9]+]]) +// CHECK2-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.3*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* @.omp_task_privates_map..4 to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META30]]), !noalias !24 +// CHECK2-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META31:![0-9]+]]) +// CHECK2-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META31]]), !noalias !24 +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1** null, i64 0, metadata [[META32:![0-9]+]]) +// CHECK2-NEXT: [[TMP31:%.*]] = call %struct.anon.1* @llvm.noalias.p0s_struct.anon.1s.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1* [[TMP8]], i8* [[TMP30]], %struct.anon.1** null, i64 0, metadata [[META32]]), !noalias !24 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK2-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !24 +// CHECK2-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store %struct.anon.1* [[TMP31]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP32:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, i32**, [2 x i32]**, [2 x %struct.S.0]**, %struct.S.0**)* +// CHECK2-NEXT: call void [[TMP35]](i8* [[TMP34]], i32** [[DOTLASTPRIV_PTR_ADDR_I]], [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !24 +// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP37:%.*]] = load i32*, i32** [[TMP36]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP39:%.*]] = load [2 x i32]*, [2 x i32]** [[TMP38]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP41:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP40]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP43:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[TMP42]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 3 +// CHECK2-NEXT: [[TMP45:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP44]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON_1]], %struct.anon.1* [[TMP32]], i32 0, i32 3 +// CHECK2-NEXT: [[TMP47:%.*]] = load %struct.S.0*, %struct.S.0** [[TMP46]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP48:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP49:%.*]] = load [2 x i32]*, [2 x i32]** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP50:%.*]] = load [2 x %struct.S.0]*, [2 x %struct.S.0]** [[DOTLASTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP51:%.*]] = load %struct.S.0*, %struct.S.0** [[DOTLASTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP52:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP52]] to i32 +// CHECK2-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !24 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32, !llvm.access.group !33 -// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !32, !llvm.access.group !33 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP44]] +// CHECK2-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP53]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !24, !llvm.access.group !33 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP54]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32, !llvm.access.group !33 -// CHECK2-NEXT: store i32 [[TMP45]], i32* [[I_I]], align 4, !noalias !32, !llvm.access.group !33 -// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[TMP38]], align 128, !llvm.access.group !33 -// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP39]], i64 0, i64 0 -// CHECK2-NEXT: store i32 [[TMP46]], i32* [[ARRAYIDX_I]], align 4, !llvm.access.group !33 -// CHECK2-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP40]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP47:%.*]] = bitcast %struct.S.0* [[ARRAYIDX5_I]] to i8* -// CHECK2-NEXT: [[TMP48:%.*]] = bitcast %struct.S.0* [[TMP41]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP47]], i8* align 4 [[TMP48]], i64 4, i1 false) #[[ATTR4]], !llvm.access.group !33 -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !32, !llvm.access.group !33 -// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP49]], 1 -// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !32, !llvm.access.group !33 +// CHECK2-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK2-NEXT: store i32 [[TMP55]], i32* [[I_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[TMP48]], align 128, !noalias !24, !llvm.access.group !33 +// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x i32], [2 x i32]* [[TMP49]], i64 0, i64 0 +// CHECK2-NEXT: store i32 [[TMP56]], i32* [[ARRAYIDX_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK2-NEXT: [[ARRAYIDX5_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP50]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP57:%.*]] = bitcast %struct.S.0* [[ARRAYIDX5_I]] to i8* +// CHECK2-NEXT: [[TMP58:%.*]] = bitcast %struct.S.0* [[TMP51]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP57]], i8* align 4 [[TMP58]], i64 4, i1 false) #[[ATTR4]], !noalias !24, !llvm.access.group !33 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !24, !llvm.access.group !33 +// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP59]], 1 +// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !24, !llvm.access.group !33 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP34:![0-9]+]] // CHECK2: omp.inner.for.end.i: -// CHECK2-NEXT: [[TMP50:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !32 -// CHECK2-NEXT: [[TMP51:%.*]] = icmp ne i32 [[TMP50]], 0 -// CHECK2-NEXT: br i1 [[TMP51]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK2-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP61:%.*]] = icmp ne i32 [[TMP60]], 0 +// CHECK2-NEXT: br i1 [[TMP61]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK2: .omp.lastprivate.then.i: -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[TMP38]], align 128 -// CHECK2-NEXT: store i32 [[TMP52]], i32* [[TMP27]], align 128 -// CHECK2-NEXT: [[TMP53:%.*]] = bitcast [2 x i32]* [[TMP29]] to i8* -// CHECK2-NEXT: [[TMP54:%.*]] = bitcast [2 x i32]* [[TMP39]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP53]], i8* align 4 [[TMP54]], i64 8, i1 false) #[[ATTR4]] -// CHECK2-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP31]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP55:%.*]] = bitcast [2 x %struct.S.0]* [[TMP40]] to %struct.S.0* -// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN_I]], i64 2 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[TMP48]], align 128, !noalias !24 +// CHECK2-NEXT: store i32 [[TMP62]], i32* [[TMP37]], align 128, !noalias !24 +// CHECK2-NEXT: [[TMP63:%.*]] = bitcast [2 x i32]* [[TMP39]] to i8* +// CHECK2-NEXT: [[TMP64:%.*]] = bitcast [2 x i32]* [[TMP49]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP63]], i8* align 4 [[TMP64]], i64 8, i1 false) #[[ATTR4]], !noalias !24 +// CHECK2-NEXT: [[ARRAY_BEGIN_I:%.*]] = getelementptr inbounds [2 x %struct.S.0], [2 x %struct.S.0]* [[TMP41]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP65:%.*]] = bitcast [2 x %struct.S.0]* [[TMP50]] to %struct.S.0* +// CHECK2-NEXT: [[TMP66:%.*]] = getelementptr [[STRUCT_S_0:%.*]], %struct.S.0* [[ARRAY_BEGIN_I]], i64 2 // CHECK2-NEXT: br label [[OMP_ARRAYCPY_BODY_I:%.*]] // CHECK2: omp.arraycpy.body.i: -// CHECK2-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[TMP55]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] +// CHECK2-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[TMP65]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] // CHECK2-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST_I:%.*]] = phi %struct.S.0* [ [[ARRAY_BEGIN_I]], [[DOTOMP_LASTPRIVATE_THEN_I]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT_I:%.*]], [[OMP_ARRAYCPY_BODY_I]] ] -// CHECK2-NEXT: [[TMP57:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* -// CHECK2-NEXT: [[TMP58:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP57]], i8* align 4 [[TMP58]], i64 4, i1 false) #[[ATTR4]] +// CHECK2-NEXT: [[TMP67:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]] to i8* +// CHECK2-NEXT: [[TMP68:%.*]] = bitcast %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP67]], i8* align 4 [[TMP68]], i64 4, i1 false) #[[ATTR4]], !noalias !24 // CHECK2-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT_I]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_DESTELEMENTPAST_I]], i32 1 // CHECK2-NEXT: [[OMP_ARRAYCPY_SRC_ELEMENT_I]] = getelementptr [[STRUCT_S_0]], %struct.S.0* [[OMP_ARRAYCPY_SRCELEMENTPAST_I]], i32 1 -// CHECK2-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP56]] +// CHECK2-NEXT: [[OMP_ARRAYCPY_DONE_I:%.*]] = icmp eq %struct.S.0* [[OMP_ARRAYCPY_DEST_ELEMENT_I]], [[TMP66]] // CHECK2-NEXT: br i1 [[OMP_ARRAYCPY_DONE_I]], label [[OMP_ARRAYCPY_DONE7_I:%.*]], label [[OMP_ARRAYCPY_BODY_I]] // CHECK2: omp.arraycpy.done7.i: -// CHECK2-NEXT: [[TMP59:%.*]] = bitcast %struct.S.0* [[TMP35]] to i8* -// CHECK2-NEXT: [[TMP60:%.*]] = bitcast %struct.S.0* [[TMP41]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP59]], i8* align 4 [[TMP60]], i64 4, i1 false) #[[ATTR4]] +// CHECK2-NEXT: [[TMP69:%.*]] = bitcast %struct.S.0* [[TMP45]] to i8* +// CHECK2-NEXT: [[TMP70:%.*]] = bitcast %struct.S.0* [[TMP51]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP69]], i8* align 4 [[TMP70]], i64 4, i1 false) #[[ATTR4]], !noalias !24 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK2: .omp_outlined..3.exit: // CHECK2-NEXT: ret i32 0 @@ -1983,66 +2003,71 @@ // CHECK3-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK3-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, double**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK3-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, double**, i32**)* -// CHECK3-NEXT: call void [[TMP25]](i8* [[TMP24]], double** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR3:[0-9]+]] -// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP27:%.*]] = load double*, double** [[TMP26]], align 8 -// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8 -// CHECK3-NEXT: [[TMP30:%.*]] = load double*, double** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP31:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP32]] to i32 -// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK3-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK3-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK3-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK3-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK3-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK3-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, double**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK3-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK3-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK3-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK3-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK3-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK3-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, double**, i32**)* +// CHECK3-NEXT: call void [[TMP35]](i8* [[TMP34]], double** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR3:[0-9]+]], !noalias !6 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP37:%.*]] = load double*, double** [[TMP36]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP40:%.*]] = load double*, double** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP42]] to i32 +// CHECK3-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK3: omp.inner.for.cond.i: -// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK3-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP33]] to i64 -// CHECK3-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK3-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP34]] +// CHECK3-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP43]] to i64 +// CHECK3-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP44]] // CHECK3-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK3: omp.inner.for.body.i: -// CHECK3-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK3-NEXT: store i32 [[TMP35]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK3-NEXT: store double 1.000000e+00, double* [[TMP30]], align 8, !llvm.access.group !15 -// CHECK3-NEXT: store i32 11, i32* [[TMP31]], align 4, !llvm.access.group !15 -// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP_I]], i32 0, i32 0 -// CHECK3-NEXT: store double* [[TMP30]], double** [[TMP36]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP_I]], i32 0, i32 1 -// CHECK3-NEXT: store i32* [[TMP31]], i32** [[TMP37]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK3-NEXT: call void @"_ZZZ4mainENK3$_0clEvENKUlvE_clEv"(%class.anon.0* nonnull align 8 dereferenceable(16) [[REF_TMP_I]]) #[[ATTR3]], !llvm.access.group !15 -// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK3-NEXT: [[ADD3_I:%.*]] = add nsw i32 [[TMP38]], 1 -// CHECK3-NEXT: store i32 [[ADD3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK3-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: store i32 [[TMP45]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: store double 1.000000e+00, double* [[TMP40]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: store i32 11, i32* [[TMP41]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP_I]], i32 0, i32 0 +// CHECK3-NEXT: store double* [[TMP40]], double** [[TMP46]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], %class.anon.0* [[REF_TMP_I]], i32 0, i32 1 +// CHECK3-NEXT: store i32* [[TMP41]], i32** [[TMP47]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: call void @"_ZZZ4mainENK3$_0clEvENKUlvE_clEv"(%class.anon.0* nonnull align 8 dereferenceable(16) [[REF_TMP_I]]) #[[ATTR3]], !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK3-NEXT: [[ADD3_I:%.*]] = add nsw i32 [[TMP48]], 1 +// CHECK3-NEXT: store i32 [[ADD3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK3: omp.inner.for.end.i: -// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK3-NEXT: [[TMP40:%.*]] = icmp ne i32 [[TMP39]], 0 -// CHECK3-NEXT: br i1 [[TMP40]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK3-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK3-NEXT: [[TMP50:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK3-NEXT: br i1 [[TMP50]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK3: .omp.lastprivate.then.i: -// CHECK3-NEXT: [[TMP41:%.*]] = load double, double* [[TMP30]], align 8 -// CHECK3-NEXT: store volatile double [[TMP41]], double* [[TMP27]], align 8 -// CHECK3-NEXT: [[TMP42:%.*]] = load i32, i32* [[TMP31]], align 4 -// CHECK3-NEXT: store i32 [[TMP42]], i32* [[TMP29]], align 4 +// CHECK3-NEXT: [[TMP51:%.*]] = load double, double* [[TMP40]], align 8, !noalias !6 +// CHECK3-NEXT: store volatile double [[TMP51]], double* [[TMP37]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP52:%.*]] = load i32, i32* [[TMP41]], align 4, !noalias !6 +// CHECK3-NEXT: store i32 [[TMP52]], i32* [[TMP39]], align 4, !noalias !6 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK3: .omp_outlined..1.exit: // CHECK3-NEXT: ret i32 0 @@ -2212,84 +2237,89 @@ // CHECK4-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK4-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK4-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, double**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK4-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, double**, i32**)* -// CHECK4-NEXT: call void [[TMP25]](i8* [[TMP24]], double** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR4:[0-9]+]] -// CHECK4-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP27:%.*]] = load double*, double** [[TMP26]], align 8 -// CHECK4-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8 -// CHECK4-NEXT: [[TMP30:%.*]] = load double*, double** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP31:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP32]] to i32 -// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK4-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK4-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK4-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK4-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK4-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK4-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, double**, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK4-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK4-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK4-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK4-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK4-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK4-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP33:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP34:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP35:%.*]] = bitcast void (i8*, ...)* [[TMP33]] to void (i8*, double**, i32**)* +// CHECK4-NEXT: call void [[TMP35]](i8* [[TMP34]], double** [[DOTLASTPRIV_PTR_ADDR_I]], i32** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR4:[0-9]+]], !noalias !6 +// CHECK4-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP37:%.*]] = load double*, double** [[TMP36]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP39:%.*]] = load i32*, i32** [[TMP38]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP40:%.*]] = load double*, double** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP42]] to i32 +// CHECK4-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK4: omp.inner.for.cond.i: -// CHECK4-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK4-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP33]] to i64 -// CHECK4-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK4-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP34]] +// CHECK4-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP43]] to i64 +// CHECK4-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP44]] // CHECK4-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK4: omp.inner.for.body.i: -// CHECK4-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK4-NEXT: store i32 [[TMP35]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK4-NEXT: store double 1.000000e+00, double* [[TMP30]], align 8, !llvm.access.group !15 -// CHECK4-NEXT: store i32 11, i32* [[TMP31]], align 4, !llvm.access.group !15 +// CHECK4-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: store i32 [[TMP45]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: store double 1.000000e+00, double* [[TMP40]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: store i32 11, i32* [[TMP41]], align 4, !noalias !6, !llvm.access.group !15 // CHECK4-NEXT: [[BLOCK_ISA_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 0 -// CHECK4-NEXT: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*), i8** [[BLOCK_ISA_I]], align 8, !noalias !14, !llvm.access.group !15 +// CHECK4-NEXT: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*), i8** [[BLOCK_ISA_I]], align 8, !noalias !6, !llvm.access.group !15 // CHECK4-NEXT: [[BLOCK_FLAGS_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 1 -// CHECK4-NEXT: store i32 1073741824, i32* [[BLOCK_FLAGS_I]], align 8, !noalias !14, !llvm.access.group !15 +// CHECK4-NEXT: store i32 1073741824, i32* [[BLOCK_FLAGS_I]], align 8, !noalias !6, !llvm.access.group !15 // CHECK4-NEXT: [[BLOCK_RESERVED_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 2 -// CHECK4-NEXT: store i32 0, i32* [[BLOCK_RESERVED_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK4-NEXT: store i32 0, i32* [[BLOCK_RESERVED_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK4-NEXT: [[BLOCK_INVOKE_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 3 -// CHECK4-NEXT: store i8* bitcast (void (i8*)* @_block_invoke to i8*), i8** [[BLOCK_INVOKE_I]], align 8, !noalias !14, !llvm.access.group !15 +// CHECK4-NEXT: store i8* bitcast (void (i8*)* @_block_invoke to i8*), i8** [[BLOCK_INVOKE_I]], align 8, !noalias !6, !llvm.access.group !15 // CHECK4-NEXT: [[BLOCK_DESCRIPTOR_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 4 -// CHECK4-NEXT: store %struct.__block_descriptor* bitcast ({ i64, i64, i8*, i8* }* @__block_descriptor_tmp.2 to %struct.__block_descriptor*), %struct.__block_descriptor** [[BLOCK_DESCRIPTOR_I]], align 8, !noalias !14, !llvm.access.group !15 +// CHECK4-NEXT: store %struct.__block_descriptor* bitcast ({ i64, i64, i8*, i8* }* @__block_descriptor_tmp.2 to %struct.__block_descriptor*), %struct.__block_descriptor** [[BLOCK_DESCRIPTOR_I]], align 8, !noalias !6, !llvm.access.group !15 // CHECK4-NEXT: [[BLOCK_CAPTURED_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 5 -// CHECK4-NEXT: [[TMP36:%.*]] = load volatile double, double* [[TMP30]], align 8, !llvm.access.group !15 -// CHECK4-NEXT: store volatile double [[TMP36]], double* [[BLOCK_CAPTURED_I]], align 8, !noalias !14, !llvm.access.group !15 +// CHECK4-NEXT: [[TMP46:%.*]] = load volatile double, double* [[TMP40]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: store volatile double [[TMP46]], double* [[BLOCK_CAPTURED_I]], align 8, !noalias !6, !llvm.access.group !15 // CHECK4-NEXT: [[BLOCK_CAPTURED3_I:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]], i32 0, i32 6 -// CHECK4-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4, !llvm.access.group !15 -// CHECK4-NEXT: store i32 [[TMP37]], i32* [[BLOCK_CAPTURED3_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK4-NEXT: [[TMP38:%.*]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]] to void ()* -// CHECK4-NEXT: [[BLOCK_LITERAL_I:%.*]] = bitcast void ()* [[TMP38]] to %struct.__block_literal_generic* -// CHECK4-NEXT: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], %struct.__block_literal_generic* [[BLOCK_LITERAL_I]], i32 0, i32 3 -// CHECK4-NEXT: [[TMP40:%.*]] = bitcast %struct.__block_literal_generic* [[BLOCK_LITERAL_I]] to i8* -// CHECK4-NEXT: [[TMP41:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK4-NEXT: [[TMP42:%.*]] = bitcast i8* [[TMP41]] to void (i8*)* -// CHECK4-NEXT: call void [[TMP42]](i8* [[TMP40]]) #[[ATTR4]], !llvm.access.group !15 -// CHECK4-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK4-NEXT: [[ADD4_I:%.*]] = add nsw i32 [[TMP43]], 1 -// CHECK4-NEXT: store i32 [[ADD4_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK4-NEXT: [[TMP47:%.*]] = load i32, i32* [[TMP41]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: store i32 [[TMP47]], i32* [[BLOCK_CAPTURED3_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: [[TMP48:%.*]] = bitcast <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, double, i32 }>* [[BLOCK_I]] to void ()* +// CHECK4-NEXT: [[BLOCK_LITERAL_I:%.*]] = bitcast void ()* [[TMP48]] to %struct.__block_literal_generic* +// CHECK4-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT___BLOCK_LITERAL_GENERIC:%.*]], %struct.__block_literal_generic* [[BLOCK_LITERAL_I]], i32 0, i32 3 +// CHECK4-NEXT: [[TMP50:%.*]] = bitcast %struct.__block_literal_generic* [[BLOCK_LITERAL_I]] to i8* +// CHECK4-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP49]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: [[TMP52:%.*]] = bitcast i8* [[TMP51]] to void (i8*)* +// CHECK4-NEXT: call void [[TMP52]](i8* [[TMP50]]) #[[ATTR4]], !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: [[TMP53:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK4-NEXT: [[ADD4_I:%.*]] = add nsw i32 [[TMP53]], 1 +// CHECK4-NEXT: store i32 [[ADD4_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK4: omp.inner.for.end.i: -// CHECK4-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK4-NEXT: [[TMP45:%.*]] = icmp ne i32 [[TMP44]], 0 -// CHECK4-NEXT: br i1 [[TMP45]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK4-NEXT: [[TMP54:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK4-NEXT: [[TMP55:%.*]] = icmp ne i32 [[TMP54]], 0 +// CHECK4-NEXT: br i1 [[TMP55]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK4: .omp.lastprivate.then.i: -// CHECK4-NEXT: [[TMP46:%.*]] = load double, double* [[TMP30]], align 8 -// CHECK4-NEXT: store volatile double [[TMP46]], double* [[TMP27]], align 8 -// CHECK4-NEXT: [[TMP47:%.*]] = load i32, i32* [[TMP31]], align 4 -// CHECK4-NEXT: store i32 [[TMP47]], i32* [[TMP29]], align 4 +// CHECK4-NEXT: [[TMP56:%.*]] = load double, double* [[TMP40]], align 8, !noalias !6 +// CHECK4-NEXT: store volatile double [[TMP56]], double* [[TMP37]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP57:%.*]] = load i32, i32* [[TMP41]], align 4, !noalias !6 +// CHECK4-NEXT: store i32 [[TMP57]], i32* [[TMP39]], align 4, !noalias !6 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK4: .omp_outlined..1.exit: // CHECK4-NEXT: ret i32 0 @@ -2446,61 +2476,66 @@ // CHECK5-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK5-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, float***, %struct.St***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK5-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK5-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK5-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, float***, %struct.St***)* -// CHECK5-NEXT: call void [[TMP27]](i8* [[TMP26]], float*** [[DOTLASTPRIV_PTR_ADDR_I]], %struct.St*** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR2:[0-9]+]] -// CHECK5-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK5-NEXT: [[TMP29:%.*]] = load float**, float*** [[TMP28]], align 8 -// CHECK5-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK5-NEXT: [[TMP31:%.*]] = load %struct.St**, %struct.St*** [[TMP30]], align 8 -// CHECK5-NEXT: [[TMP32:%.*]] = load float**, float*** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP33:%.*]] = load %struct.St**, %struct.St*** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK5-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP34]] to i32 -// CHECK5-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK5-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK5-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK5-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK5-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK5-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK5-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, float***, %struct.St***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK5-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK5-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK5-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK5-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK5-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK5-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK5-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, float***, %struct.St***)* +// CHECK5-NEXT: call void [[TMP37]](i8* [[TMP36]], float*** [[DOTLASTPRIV_PTR_ADDR_I]], %struct.St*** [[DOTLASTPRIV_PTR_ADDR1_I]]) #[[ATTR2:[0-9]+]], !noalias !6 +// CHECK5-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK5-NEXT: [[TMP39:%.*]] = load float**, float*** [[TMP38]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK5-NEXT: [[TMP41:%.*]] = load %struct.St**, %struct.St*** [[TMP40]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP42:%.*]] = load float**, float*** [[DOTLASTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP43:%.*]] = load %struct.St**, %struct.St*** [[DOTLASTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP44:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP44]] to i32 +// CHECK5-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK5: omp.inner.for.cond.i: -// CHECK5-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK5-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP35]] to i64 -// CHECK5-NEXT: [[TMP36:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK5-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP36]] +// CHECK5-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK5-NEXT: [[CONV2_I:%.*]] = sext i32 [[TMP45]] to i64 +// CHECK5-NEXT: [[TMP46:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK5-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV2_I]], [[TMP46]] // CHECK5-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK5: omp.inner.for.body.i: -// CHECK5-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK5-NEXT: store i32 [[TMP37]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK5-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK5-NEXT: [[ADD3_I:%.*]] = add nsw i32 [[TMP38]], 1 -// CHECK5-NEXT: store i32 [[ADD3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK5-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK5-NEXT: store i32 [[TMP47]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK5-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK5-NEXT: [[ADD3_I:%.*]] = add nsw i32 [[TMP48]], 1 +// CHECK5-NEXT: store i32 [[ADD3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK5: omp.inner.for.end.i: -// CHECK5-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK5-NEXT: [[TMP40:%.*]] = icmp ne i32 [[TMP39]], 0 -// CHECK5-NEXT: br i1 [[TMP40]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK5-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK5-NEXT: [[TMP50:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK5-NEXT: br i1 [[TMP50]], label [[DOTOMP_LASTPRIVATE_THEN_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK5: .omp.lastprivate.then.i: -// CHECK5-NEXT: [[TMP41:%.*]] = load float*, float** [[TMP32]], align 8 -// CHECK5-NEXT: store float* [[TMP41]], float** [[TMP29]], align 8 -// CHECK5-NEXT: [[TMP42:%.*]] = load %struct.St*, %struct.St** [[TMP33]], align 8 -// CHECK5-NEXT: store %struct.St* [[TMP42]], %struct.St** [[TMP31]], align 8 +// CHECK5-NEXT: [[TMP51:%.*]] = load float*, float** [[TMP42]], align 8, !noalias !6 +// CHECK5-NEXT: store float* [[TMP51]], float** [[TMP39]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP52:%.*]] = load %struct.St*, %struct.St** [[TMP43]], align 8, !noalias !6 +// CHECK5-NEXT: store %struct.St* [[TMP52]], %struct.St** [[TMP41]], align 8, !noalias !6 // CHECK5-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK5: .omp_outlined..1.exit: // CHECK5-NEXT: ret i32 0 @@ -2625,65 +2660,66 @@ // CHECK6-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 8 // CHECK6-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK6-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK6-NEXT: store i8* [[TMP19]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 0 -// CHECK6-NEXT: [[TMP22:%.*]] = load i32*, i32** [[TMP21]], align 8 -// CHECK6-NEXT: [[TMP23:%.*]] = load i32, i32* [[TMP22]], align 4 -// CHECK6-NEXT: store i32 [[TMP23]], i32* [[DOTLINEAR_START_I]], align 4, !noalias !14 -// CHECK6-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 -// CHECK6-NEXT: [[TMP25:%.*]] = load i32*, i32** [[TMP24]], align 8 -// CHECK6-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP25]], align 4 -// CHECK6-NEXT: store i32 [[TMP26]], i32* [[DOTLINEAR_START1_I]], align 4, !noalias !14 -// CHECK6-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 0 -// CHECK6-NEXT: [[TMP28:%.*]] = load i32*, i32** [[TMP27]], align 8 -// CHECK6-NEXT: [[TMP29:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK6-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP29]] to i32 -// CHECK6-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK6-NEXT: [[TMP20:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK6-NEXT: [[TMP21:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP20]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK6-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK6-NEXT: [[TMP23:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP19]], i8* [[TMP22]], i8** null, i64 0, metadata [[META9]]), !noalias !6 +// CHECK6-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK6-NEXT: [[TMP25:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP24]], %struct.anon** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK6-NEXT: store i32* [[TMP21]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i64 [[TMP11]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i64 [[TMP13]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i64 [[TMP15]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i32 [[TMP17]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK6-NEXT: store i8* [[TMP23]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store %struct.anon* [[TMP25]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP26:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP26]], i32 0, i32 0 +// CHECK6-NEXT: [[TMP28:%.*]] = load i32*, i32** [[TMP27]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4, !noalias !6 +// CHECK6-NEXT: store i32 [[TMP29]], i32* [[DOTLINEAR_START_I]], align 4, !noalias !6 +// CHECK6-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP26]], i32 0, i32 1 +// CHECK6-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !6 +// CHECK6-NEXT: store i32 [[TMP32]], i32* [[DOTLINEAR_START1_I]], align 4, !noalias !6 +// CHECK6-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP26]], i32 0, i32 0 +// CHECK6-NEXT: [[TMP34:%.*]] = load i32*, i32** [[TMP33]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP35:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[CONV_I:%.*]] = trunc i64 [[TMP35]] to i32 +// CHECK6-NEXT: store i32 [[CONV_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK6: omp.inner.for.cond.i: -// CHECK6-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: [[CONV3_I:%.*]] = sext i32 [[TMP30]] to i64 -// CHECK6-NEXT: [[TMP31:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV3_I]], [[TMP31]] +// CHECK6-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: [[CONV3_I:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK6-NEXT: [[TMP37:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV3_I]], [[TMP37]] // CHECK6-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[OMP_INNER_FOR_END_I:%.*]] // CHECK6: omp.inner.for.body.i: -// CHECK6-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: store i32 [[TMP32]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTLINEAR_START1_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: [[ADD5_I:%.*]] = add nsw i32 [[TMP33]], [[TMP34]] -// CHECK6-NEXT: store i32 [[ADD5_I]], i32* [[J_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: [[TMP35:%.*]] = load i32, i32* [[J_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP35]], 1 -// CHECK6-NEXT: store i32 [[INC_I]], i32* [[J_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP36]], 1 -// CHECK6-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] +// CHECK6-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: store i32 [[TMP38]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTLINEAR_START1_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: [[ADD5_I:%.*]] = add nsw i32 [[TMP39]], [[TMP40]] +// CHECK6-NEXT: store i32 [[ADD5_I]], i32* [[J_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: [[TMP41:%.*]] = load i32, i32* [[J_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP41]], 1 +// CHECK6-NEXT: store i32 [[INC_I]], i32* [[J_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP42]], 1 +// CHECK6-NEXT: store i32 [[ADD6_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !11 +// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP12:![0-9]+]] // CHECK6: omp.inner.for.end.i: -// CHECK6-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK6-NEXT: [[TMP38:%.*]] = icmp ne i32 [[TMP37]], 0 -// CHECK6-NEXT: br i1 [[TMP38]], label [[DOTOMP_LINEAR_PU_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK6-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK6-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK6-NEXT: br i1 [[TMP44]], label [[DOTOMP_LINEAR_PU_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK6: .omp.linear.pu.i: -// CHECK6-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTLINEAR_START1_I]], align 4, !noalias !14 -// CHECK6-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP39]], 10 -// CHECK6-NEXT: store i32 [[ADD7_I]], i32* [[J_I]], align 4, !noalias !14 +// CHECK6-NEXT: [[TMP45:%.*]] = load i32, i32* [[DOTLINEAR_START1_I]], align 4, !noalias !6 +// CHECK6-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP45]], 10 +// CHECK6-NEXT: store i32 [[ADD7_I]], i32* [[J_I]], align 4, !noalias !6 // CHECK6-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK6: .omp_outlined..1.exit: // CHECK6-NEXT: ret i32 0 Index: clang/test/OpenMP/parallel_master_taskloop_simd_private_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_master_taskloop_simd_private_codegen.cpp +++ clang/test/OpenMP/parallel_master_taskloop_simd_private_codegen.cpp @@ -228,7 +228,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) @@ -351,7 +352,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/parallel_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_reduction_task_codegen.cpp +++ clang/test/OpenMP/parallel_reduction_task_codegen.cpp @@ -398,61 +398,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -868,61 +872,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/parallel_sections_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/parallel_sections_reduction_task_codegen.cpp +++ clang/test/OpenMP/parallel_sections_reduction_task_codegen.cpp @@ -440,61 +440,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -952,61 +956,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/sections_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/sections_reduction_task_codegen.cpp +++ clang/test/OpenMP/sections_reduction_task_codegen.cpp @@ -445,61 +445,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -961,61 +965,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5:[0-9]+]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/target_parallel_codegen.cpp =================================================================== --- clang/test/OpenMP/target_parallel_codegen.cpp +++ clang/test/OpenMP/target_parallel_codegen.cpp @@ -566,22 +566,22 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK1-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META12]]), !noalias !15 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META17]]), !noalias !15 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !15 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !15 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: omp_offload.failed.i: -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]], !noalias !15 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .omp_outlined..1.exit: // CHECK1-NEXT: ret i32 0 @@ -1596,22 +1596,22 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK2-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK2-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META12]]), !noalias !15 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META17]]), !noalias !15 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !15 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !15 +// CHECK2-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK2-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: omp_offload.failed.i: -// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]] +// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]], !noalias !15 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .omp_outlined..1.exit: // CHECK2-NEXT: ret i32 0 @@ -2623,22 +2623,22 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK3-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META18:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META18]]), !noalias !16 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !16 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK3: omp_offload.failed.i: -// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]], !noalias !16 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK3: .omp_outlined..1.exit: // CHECK3-NEXT: ret i32 0 @@ -3629,22 +3629,22 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 4 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK4-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK4-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META18:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META18]]), !noalias !16 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !16 +// CHECK4-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK4-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK4: omp_offload.failed.i: -// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]] +// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]], !noalias !16 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK4: .omp_outlined..1.exit: // CHECK4-NEXT: ret i32 0 @@ -6264,22 +6264,22 @@ // CHECK17-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK17-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK17-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK17-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 -// CHECK17-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK17-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK17-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK17-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK17-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META12]]), !noalias !15 +// CHECK17-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK17-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META17]]), !noalias !15 +// CHECK17-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !15 +// CHECK17-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !15 +// CHECK17-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK17-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK17: omp_offload.failed.i: -// CHECK17-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]] +// CHECK17-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]], !noalias !15 // CHECK17-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK17: .omp_outlined..1.exit: // CHECK17-NEXT: ret i32 0 @@ -7294,22 +7294,22 @@ // CHECK18-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK18-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK18-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK18-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 -// CHECK18-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK18-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK18-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK18-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK18-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META12]]), !noalias !15 +// CHECK18-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK18-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META17]]), !noalias !15 +// CHECK18-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !15 +// CHECK18-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !15 +// CHECK18-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK18-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK18: omp_offload.failed.i: -// CHECK18-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]] +// CHECK18-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]], !noalias !15 // CHECK18-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK18: .omp_outlined..1.exit: // CHECK18-NEXT: ret i32 0 @@ -8321,22 +8321,22 @@ // CHECK19-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 4 // CHECK19-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK19-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK19-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK19-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK19-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK19-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK19-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK19-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META18:![0-9]+]]) +// CHECK19-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META18]]), !noalias !16 +// CHECK19-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !16 +// CHECK19-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK19-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK19: omp_offload.failed.i: -// CHECK19-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]] +// CHECK19-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]], !noalias !16 // CHECK19-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK19: .omp_outlined..1.exit: // CHECK19-NEXT: ret i32 0 @@ -9327,22 +9327,22 @@ // CHECK20-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 4 // CHECK20-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK20-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK20-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK20-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK20-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK20-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK20-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK20-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META18:![0-9]+]]) +// CHECK20-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META18]]), !noalias !16 +// CHECK20-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !16 +// CHECK20-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK20-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK20: omp_offload.failed.i: -// CHECK20-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]] +// CHECK20-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l100() #[[ATTR4]], !noalias !16 // CHECK20-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK20: .omp_outlined..1.exit: // CHECK20-NEXT: ret i32 0 Index: clang/test/OpenMP/target_parallel_debug_codegen.cpp =================================================================== --- clang/test/OpenMP/target_parallel_debug_codegen.cpp +++ clang/test/OpenMP/target_parallel_debug_codegen.cpp @@ -65,7 +65,7 @@ return 0; } // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23_debug__ -// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]]* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0:[0-9]+]] !dbg [[DBG24:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]]* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0:[0-9]+]] !dbg [[DBG23:![0-9]+]] !noalias !39 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]] addrspace(1)*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 @@ -77,54 +77,57 @@ // CHECK1-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [4 x i8*], align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META39:![0-9]+]], metadata !DIExpression()), !dbg [[DBG40:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META42:![0-9]+]], metadata !DIExpression()), !dbg [[DBG43:![0-9]+]] // CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META41:![0-9]+]], metadata !DIExpression()), !dbg [[DBG42:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META44:![0-9]+]], metadata !DIExpression()), !dbg [[DBG45:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META43:![0-9]+]], metadata !DIExpression()), !dbg [[DBG44:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META46:![0-9]+]], metadata !DIExpression()), !dbg [[DBG47:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META45:![0-9]+]], metadata !DIExpression()), !dbg [[DBG46:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG47:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG47]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG47]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG47]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG47]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP3]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG47]] -// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG47]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG47]] -// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast i8 addrspace(1)* [[TMP5]] to i8*, !dbg [[DBG47]] -// CHECK1-NEXT: store i8* [[TMP6]], i8** [[_TMP2]], align 8, !dbg [[DBG47]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG47]] -// CHECK1-NEXT: [[TMP8:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i8 2, i1 false, i1 true), !dbg [[DBG47]] -// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP8]], -1, !dbg [[DBG47]] -// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG47]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META48:![0-9]+]], metadata !DIExpression()), !dbg [[DBG49:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG50:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META39:![0-9]+]]), !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG50]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP5:%.*]] = call [10 x [10 x i32]]* @llvm.noalias.p0a10a10i32.p0i8.p0p0a10a10i32.i64([10 x [10 x i32]]* [[TMP4]], i8* null, [10 x [10 x i32]]** [[B_ADDR]], i64 0, metadata [[META39]]), !dbg [[DBG50]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP5]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP8:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP7]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META39]]), !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8 addrspace(1)* [[TMP8]] to i8*, !dbg [[DBG50]] +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[_TMP2]], align 8, !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG50]] +// CHECK1-NEXT: [[TMP11:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i8 2, i1 false, i1 true), !dbg [[DBG50]] +// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP11]], -1, !dbg [[DBG50]] +// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG50]] // CHECK1: user_code.entry: -// CHECK1-NEXT: [[TMP9:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB3:[0-9]+]]) -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG48:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG48]] -// CHECK1-NEXT: store i32 [[TMP10]], i32* [[CONV]], align 4, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP13:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP2]] to i8*, !dbg [[DBG48]] -// CHECK1-NEXT: store i8* [[TMP13]], i8** [[TMP12]], align 8, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP15:%.*]] = inttoptr i64 [[TMP11]] to i8*, !dbg [[DBG48]] -// CHECK1-NEXT: store i8* [[TMP15]], i8** [[TMP14]], align 8, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast [10 x [10 x i32]]* [[TMP4]] to i8*, !dbg [[DBG48]] -// CHECK1-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG48]] -// CHECK1-NEXT: store i8* [[TMP7]], i8** [[TMP18]], align 8, !dbg [[DBG48]] -// CHECK1-NEXT: [[TMP19:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG48]] -// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB3]], i32 [[TMP9]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i64, [10 x [10 x i32]]*, i8*)* @__omp_outlined__ to i8*), i8* null, i8** [[TMP19]], i64 4), !dbg [[DBG48]] -// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB5:[0-9]+]], i8 2, i1 true), !dbg [[DBG49:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG51:![0-9]+]] +// CHECK1-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB3:[0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG51:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG51]] +// CHECK1-NEXT: store i32 [[TMP13]], i32* [[CONV]], align 4, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP16:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP3]] to i8*, !dbg [[DBG51]] +// CHECK1-NEXT: store i8* [[TMP16]], i8** [[TMP15]], align 8, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP18:%.*]] = inttoptr i64 [[TMP14]] to i8*, !dbg [[DBG51]] +// CHECK1-NEXT: store i8* [[TMP18]], i8** [[TMP17]], align 8, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP20:%.*]] = bitcast [10 x [10 x i32]]* [[TMP6]] to i8*, !dbg [[DBG51]] +// CHECK1-NEXT: store i8* [[TMP20]], i8** [[TMP19]], align 8, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG51]] +// CHECK1-NEXT: store i8* [[TMP10]], i8** [[TMP21]], align 8, !dbg [[DBG51]] +// CHECK1-NEXT: [[TMP22:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG51]] +// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB3]], i32 [[TMP12]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i64, [10 x [10 x i32]]*, i8*)* @__omp_outlined__ to i8*), i8* null, i8** [[TMP22]], i64 4), !dbg [[DBG51]] +// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB5:[0-9]+]], i8 2, i1 true), !dbg [[DBG52:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG54:![0-9]+]] // CHECK1: worker.exit: -// CHECK1-NEXT: ret void, !dbg [[DBG47]] +// CHECK1-NEXT: ret void, !dbg [[DBG50]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined___debug__ -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]]* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG52:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]]* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG55:![0-9]+]] !noalias !62 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -141,85 +144,88 @@ // CHECK1-NEXT: [[H:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META59:![0-9]+]], metadata !DIExpression()), !dbg [[DBG60:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META65:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META61:![0-9]+]], metadata !DIExpression()), !dbg [[DBG60]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META67:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META62:![0-9]+]], metadata !DIExpression()), !dbg [[DBG63:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META68:![0-9]+]], metadata !DIExpression()), !dbg [[DBG69:![0-9]+]] // CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META64:![0-9]+]], metadata !DIExpression()), !dbg [[DBG65:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META70:![0-9]+]], metadata !DIExpression()), !dbg [[DBG71:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META66:![0-9]+]], metadata !DIExpression()), !dbg [[DBG67:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META72:![0-9]+]], metadata !DIExpression()), !dbg [[DBG73:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META68:![0-9]+]], metadata !DIExpression()), !dbg [[DBG69:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG70:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG70]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG70]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG70]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG70]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP3]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG70]] -// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG70]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG70]] -// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast i8 addrspace(1)* [[TMP5]] to i8*, !dbg [[DBG70]] -// CHECK1-NEXT: store i8* [[TMP6]], i8** [[_TMP2]], align 8, !dbg [[DBG70]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG70]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]* [[B3]], metadata [[META71:![0-9]+]], metadata !DIExpression()), !dbg [[DBG60]] -// CHECK1-NEXT: [[TMP8:%.*]] = bitcast [10 x [10 x i32]]* [[B3]] to i8*, !dbg [[DBG70]] -// CHECK1-NEXT: [[TMP9:%.*]] = bitcast [10 x [10 x i32]]* [[TMP4]] to i8*, !dbg [[DBG70]] -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP8]], i8* align 4 [[TMP9]], i64 400, i1 false), !dbg [[DBG70]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META72:![0-9]+]], metadata !DIExpression()), !dbg [[DBG75:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 1, !dbg [[DBG76:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG76]] -// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX4]], i64 0, i64 1, !dbg [[DBG76]] -// CHECK1-NEXT: store i32* [[ARRAYIDX5]], i32** [[F]], align 8, !dbg [[DBG75]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META77:![0-9]+]], metadata !DIExpression()), !dbg [[DBG78:![0-9]+]] -// CHECK1-NEXT: store i32* [[A_ADDR]], i32** [[G]], align 8, !dbg [[DBG78]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META79:![0-9]+]], metadata !DIExpression()), !dbg [[DBG80:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B3]], i64 0, i64 1, !dbg [[DBG81:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG81]] -// CHECK1-NEXT: store i32* [[ARRAYIDX7]], i32** [[H]], align 8, !dbg [[DBG80]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META82:![0-9]+]], metadata !DIExpression()), !dbg [[DBG83:![0-9]+]] -// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG83]] -// CHECK1-NEXT: store i32 5, i32* [[A_ADDR]], align 4, !dbg [[DBG84:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B3]], i64 0, i64 0, !dbg [[DBG85:![0-9]+]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG86:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP10]] to i64, !dbg [[DBG85]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX8]], i64 0, i64 [[IDXPROM]], !dbg [[DBG85]] -// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX9]], align 4, !dbg [[DBG87:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG88:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX10]], i64 0, i64 0, !dbg [[DBG88]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG89:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP11]] to i64, !dbg [[DBG88]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX11]], i64 0, i64 [[IDXPROM12]], !dbg [[DBG88]] -// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX13]], align 4, !dbg [[DBG90:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG91:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX14]], i64 0, i64 0, !dbg [[DBG91]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG92:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM16:%.*]] = sext i32 [[TMP12]] to i64, !dbg [[DBG91]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX15]], i64 0, i64 [[IDXPROM16]], !dbg [[DBG91]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[ARRAYIDX17]], align 4, !dbg [[DBG91]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B3]], i64 0, i64 0, !dbg [[DBG93:![0-9]+]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG94:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP14]] to i64, !dbg [[DBG93]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG93]] -// CHECK1-NEXT: store i32 [[TMP13]], i32* [[ARRAYIDX20]], align 4, !dbg [[DBG95:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B3]], i64 0, i64 0, !dbg [[DBG96:![0-9]+]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG97:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP15]] to i64, !dbg [[DBG96]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG96]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[ARRAYIDX23]], align 4, !dbg [[DBG96]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i8, i8* [[TMP7]], align 1, !dbg [[DBG98:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP17]] to i1, !dbg [[DBG98]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG98]] -// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP16]], !dbg [[DBG98]] -// CHECK1-NEXT: [[TOBOOL24:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG98]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL24]] to i8, !dbg [[DBG98]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], i8* [[TMP7]], align 1, !dbg [[DBG98]] -// CHECK1-NEXT: ret void, !dbg [[DBG99:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META74:![0-9]+]], metadata !DIExpression()), !dbg [[DBG75:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG76:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META62:![0-9]+]]), !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG76]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP5:%.*]] = call [10 x [10 x i32]]* @llvm.noalias.p0a10a10i32.p0i8.p0p0a10a10i32.i64([10 x [10 x i32]]* [[TMP4]], i8* null, [10 x [10 x i32]]** [[B_ADDR]], i64 0, metadata [[META62]]), !dbg [[DBG76]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP5]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP8:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP7]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META62]]), !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8 addrspace(1)* [[TMP8]] to i8*, !dbg [[DBG76]] +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[_TMP2]], align 8, !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG76]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]* [[B3]], metadata [[META77:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66]] +// CHECK1-NEXT: [[TMP11:%.*]] = bitcast [10 x [10 x i32]]* [[B3]] to i8*, !dbg [[DBG76]] +// CHECK1-NEXT: [[TMP12:%.*]] = bitcast [10 x [10 x i32]]* [[TMP6]] to i8*, !dbg [[DBG76]] +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP11]], i8* align 4 [[TMP12]], i64 400, i1 false), !dbg [[DBG76]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META78:![0-9]+]], metadata !DIExpression()), !dbg [[DBG81:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 1, !dbg [[DBG82:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG82]] +// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX4]], i64 0, i64 1, !dbg [[DBG82]] +// CHECK1-NEXT: store i32* [[ARRAYIDX5]], i32** [[F]], align 8, !dbg [[DBG81]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META83:![0-9]+]], metadata !DIExpression()), !dbg [[DBG84:![0-9]+]] +// CHECK1-NEXT: store i32* [[A_ADDR]], i32** [[G]], align 8, !dbg [[DBG84]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META85:![0-9]+]], metadata !DIExpression()), !dbg [[DBG86:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B3]], i64 0, i64 1, !dbg [[DBG87:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG87]] +// CHECK1-NEXT: store i32* [[ARRAYIDX7]], i32** [[H]], align 8, !dbg [[DBG86]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META88:![0-9]+]], metadata !DIExpression()), !dbg [[DBG89:![0-9]+]] +// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG89]] +// CHECK1-NEXT: store i32 5, i32* [[A_ADDR]], align 4, !dbg [[DBG90:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B3]], i64 0, i64 0, !dbg [[DBG91:![0-9]+]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG92:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG91]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX8]], i64 0, i64 [[IDXPROM]], !dbg [[DBG91]] +// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX9]], align 4, !dbg [[DBG93:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG94:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX10]], i64 0, i64 0, !dbg [[DBG94]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG95:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP14]] to i64, !dbg [[DBG94]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX11]], i64 0, i64 [[IDXPROM12]], !dbg [[DBG94]] +// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX13]], align 4, !dbg [[DBG96:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG97:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX14]], i64 0, i64 0, !dbg [[DBG97]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG98:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM16:%.*]] = sext i32 [[TMP15]] to i64, !dbg [[DBG97]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX15]], i64 0, i64 [[IDXPROM16]], !dbg [[DBG97]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[ARRAYIDX17]], align 4, !dbg [[DBG97]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B3]], i64 0, i64 0, !dbg [[DBG99:![0-9]+]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG100:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP17]] to i64, !dbg [[DBG99]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG99]] +// CHECK1-NEXT: store i32 [[TMP16]], i32* [[ARRAYIDX20]], align 4, !dbg [[DBG101:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B3]], i64 0, i64 0, !dbg [[DBG102:![0-9]+]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG103:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP18]] to i64, !dbg [[DBG102]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG102]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[ARRAYIDX23]], align 4, !dbg [[DBG102]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i8, i8* [[TMP10]], align 1, !dbg [[DBG104:![0-9]+]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP20]] to i1, !dbg [[DBG104]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG104]] +// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP19]], !dbg [[DBG104]] +// CHECK1-NEXT: [[TOBOOL24:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG104]] +// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL24]] to i8, !dbg [[DBG104]] +// CHECK1-NEXT: store i8 [[FROMBOOL]], i8* [[TMP10]], align 1, !dbg [[DBG104]] +// CHECK1-NEXT: ret void, !dbg [[DBG105:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__ -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG100:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG106:![0-9]+]] !noalias !113 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -228,64 +234,66 @@ // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META107:![0-9]+]], metadata !DIExpression()), !dbg [[DBG108:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META116:![0-9]+]], metadata !DIExpression()), !dbg [[DBG117:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META109:![0-9]+]], metadata !DIExpression()), !dbg [[DBG108]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META118:![0-9]+]], metadata !DIExpression()), !dbg [[DBG117]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META110:![0-9]+]], metadata !DIExpression()), !dbg [[DBG108]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META119:![0-9]+]], metadata !DIExpression()), !dbg [[DBG117]] // CHECK1-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META111:![0-9]+]], metadata !DIExpression()), !dbg [[DBG108]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META120:![0-9]+]], metadata !DIExpression()), !dbg [[DBG117]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META112:![0-9]+]], metadata !DIExpression()), !dbg [[DBG108]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META121:![0-9]+]], metadata !DIExpression()), !dbg [[DBG117]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META113:![0-9]+]], metadata !DIExpression()), !dbg [[DBG108]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG114:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP5]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG114]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8* [[TMP8]] to i8 addrspace(1)*, !dbg [[DBG114]] -// CHECK1-NEXT: call void @__omp_outlined___debug__(i32* [[TMP3]], i32* [[TMP4]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP9]], i32 [[TMP6]], [10 x [10 x i32]]* [[TMP7]], i8 addrspace(1)* [[TMP10]]) #[[ATTR3:[0-9]+]], !dbg [[DBG114]] -// CHECK1-NEXT: ret void, !dbg [[DBG114]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META122:![0-9]+]], metadata !DIExpression()), !dbg [[DBG117]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG123:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP4:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP3]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META113:![0-9]+]]), !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META113]]), !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP9:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP7]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG123]] +// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast i8* [[TMP10]] to i8 addrspace(1)*, !dbg [[DBG123]] +// CHECK1-NEXT: call void @__omp_outlined___debug__(i32* [[TMP4]], i32* [[TMP6]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP11]], i32 [[TMP8]], [10 x [10 x i32]]* [[TMP9]], i8 addrspace(1)* [[TMP12]]) #[[ATTR4:[0-9]+]], !dbg [[DBG123]] +// CHECK1-NEXT: ret void, !dbg [[DBG123]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23 -// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR4:[0-9]+]] !dbg [[DBG98:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR6:[0-9]+]] !dbg [[DBG124:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]]*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META118:![0-9]+]], metadata !DIExpression()), !dbg [[DBG119:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META127:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128:![0-9]+]] // CHECK1-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META120:![0-9]+]], metadata !DIExpression()), !dbg [[DBG119]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META129:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META121:![0-9]+]], metadata !DIExpression()), !dbg [[DBG119]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META130:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META122:![0-9]+]], metadata !DIExpression()), !dbg [[DBG119]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG123:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG123]] -// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG123]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG123]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG123]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG123]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG123]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG123]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP3]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG123]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast i8* [[TMP6]] to i8 addrspace(1)*, !dbg [[DBG123]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP7]], i32 [[TMP4]], [10 x [10 x i32]]* [[TMP5]], i8 addrspace(1)* [[TMP8]]) #[[ATTR3]], !dbg [[DBG123]] -// CHECK1-NEXT: ret void, !dbg [[DBG123]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META131:![0-9]+]], metadata !DIExpression()), !dbg [[DBG128]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG132:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG132]] +// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG132]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG132]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG132]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG132]] +// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG132]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG132]] +// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP3]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG132]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast i8* [[TMP6]] to i8 addrspace(1)*, !dbg [[DBG132]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l23_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP7]], i32 [[TMP4]], [10 x [10 x i32]]* [[TMP5]], i8 addrspace(1)* [[TMP8]]) #[[ATTR4]], !dbg [[DBG132]] +// CHECK1-NEXT: ret void, !dbg [[DBG132]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37_debug__ -// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG124:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG133:![0-9]+]] !noalias !138 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]] addrspace(1)*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 @@ -297,55 +305,58 @@ // CHECK1-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [4 x i8*], align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META129:![0-9]+]], metadata !DIExpression()), !dbg [[DBG130:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META141:![0-9]+]], metadata !DIExpression()), !dbg [[DBG142:![0-9]+]] // CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META131:![0-9]+]], metadata !DIExpression()), !dbg [[DBG132:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META143:![0-9]+]], metadata !DIExpression()), !dbg [[DBG144:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]] addrspace(1)* [[B]], [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META133:![0-9]+]], metadata !DIExpression()), !dbg [[DBG134:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META145:![0-9]+]], metadata !DIExpression()), !dbg [[DBG146:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META135:![0-9]+]], metadata !DIExpression()), !dbg [[DBG136:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG137:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG137]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG137]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG137]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG137]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP3]] to [10 x [10 x i32]]*, !dbg [[DBG137]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP4]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG137]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG137]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG137]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast i8 addrspace(1)* [[TMP6]] to i8*, !dbg [[DBG137]] -// CHECK1-NEXT: store i8* [[TMP7]], i8** [[_TMP2]], align 8, !dbg [[DBG137]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG137]] -// CHECK1-NEXT: [[TMP9:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB7:[0-9]+]], i8 2, i1 false, i1 true), !dbg [[DBG137]] -// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP9]], -1, !dbg [[DBG137]] -// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG137]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META147:![0-9]+]], metadata !DIExpression()), !dbg [[DBG148:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG149:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META138:![0-9]+]]), !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG149]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP5:%.*]] = call [10 x [10 x i32]] addrspace(1)* @llvm.noalias.p1a10a10i32.p0i8.p0p1a10a10i32.i64([10 x [10 x i32]] addrspace(1)* [[TMP4]], i8* null, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], i64 0, metadata [[META138]]), !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP5]] to [10 x [10 x i32]]*, !dbg [[DBG149]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP6]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP9:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP8]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META138]]), !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8 addrspace(1)* [[TMP9]] to i8*, !dbg [[DBG149]] +// CHECK1-NEXT: store i8* [[TMP10]], i8** [[_TMP2]], align 8, !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG149]] +// CHECK1-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB7:[0-9]+]], i8 2, i1 false, i1 true), !dbg [[DBG149]] +// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP12]], -1, !dbg [[DBG149]] +// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG149]] // CHECK1: user_code.entry: -// CHECK1-NEXT: [[TMP10:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB9:[0-9]+]]) -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG138:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG138]] -// CHECK1-NEXT: store i32 [[TMP11]], i32* [[CONV]], align 4, !dbg [[DBG138]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG138]] -// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG138]] -// CHECK1-NEXT: [[TMP14:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP2]] to i8*, !dbg [[DBG138]] -// CHECK1-NEXT: store i8* [[TMP14]], i8** [[TMP13]], align 8, !dbg [[DBG138]] -// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG138]] -// CHECK1-NEXT: [[TMP16:%.*]] = inttoptr i64 [[TMP12]] to i8*, !dbg [[DBG138]] -// CHECK1-NEXT: store i8* [[TMP16]], i8** [[TMP15]], align 8, !dbg [[DBG138]] -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG138]] -// CHECK1-NEXT: [[TMP18:%.*]] = bitcast [10 x [10 x i32]]* [[TMP5]] to i8*, !dbg [[DBG138]] -// CHECK1-NEXT: store i8* [[TMP18]], i8** [[TMP17]], align 8, !dbg [[DBG138]] -// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG138]] -// CHECK1-NEXT: store i8* [[TMP8]], i8** [[TMP19]], align 8, !dbg [[DBG138]] -// CHECK1-NEXT: [[TMP20:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG138]] -// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB9]], i32 [[TMP10]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i64, [10 x [10 x i32]]*, i8*)* @__omp_outlined__2 to i8*), i8* null, i8** [[TMP20]], i64 4), !dbg [[DBG138]] -// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB11:[0-9]+]], i8 2, i1 true), !dbg [[DBG139:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG141:![0-9]+]] +// CHECK1-NEXT: [[TMP13:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB9:[0-9]+]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG150:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG150]] +// CHECK1-NEXT: store i32 [[TMP14]], i32* [[CONV]], align 4, !dbg [[DBG150]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG150]] +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG150]] +// CHECK1-NEXT: [[TMP17:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP3]] to i8*, !dbg [[DBG150]] +// CHECK1-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8, !dbg [[DBG150]] +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG150]] +// CHECK1-NEXT: [[TMP19:%.*]] = inttoptr i64 [[TMP15]] to i8*, !dbg [[DBG150]] +// CHECK1-NEXT: store i8* [[TMP19]], i8** [[TMP18]], align 8, !dbg [[DBG150]] +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG150]] +// CHECK1-NEXT: [[TMP21:%.*]] = bitcast [10 x [10 x i32]]* [[TMP7]] to i8*, !dbg [[DBG150]] +// CHECK1-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !dbg [[DBG150]] +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG150]] +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[TMP22]], align 8, !dbg [[DBG150]] +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG150]] +// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB9]], i32 [[TMP13]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i64, [10 x [10 x i32]]*, i8*)* @__omp_outlined__2 to i8*), i8* null, i8** [[TMP23]], i64 4), !dbg [[DBG150]] +// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB11:[0-9]+]], i8 2, i1 true), !dbg [[DBG151:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG153:![0-9]+]] // CHECK1: worker.exit: -// CHECK1-NEXT: ret void, !dbg [[DBG137]] +// CHECK1-NEXT: ret void, !dbg [[DBG149]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined___debug__1 -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG142:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG154:![0-9]+]] !noalias !157 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -361,74 +372,77 @@ // CHECK1-NEXT: [[H:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META145:![0-9]+]], metadata !DIExpression()), !dbg [[DBG146:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META160:![0-9]+]], metadata !DIExpression()), !dbg [[DBG161:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META147:![0-9]+]], metadata !DIExpression()), !dbg [[DBG146]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META162:![0-9]+]], metadata !DIExpression()), !dbg [[DBG161]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META148:![0-9]+]], metadata !DIExpression()), !dbg [[DBG149:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META163:![0-9]+]], metadata !DIExpression()), !dbg [[DBG164:![0-9]+]] // CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META150:![0-9]+]], metadata !DIExpression()), !dbg [[DBG151:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META165:![0-9]+]], metadata !DIExpression()), !dbg [[DBG166:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]] addrspace(1)* [[B]], [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META152:![0-9]+]], metadata !DIExpression()), !dbg [[DBG153:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META167:![0-9]+]], metadata !DIExpression()), !dbg [[DBG168:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META154:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG156:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG156]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG156]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG156]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG156]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP3]] to [10 x [10 x i32]]*, !dbg [[DBG156]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP4]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG156]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG156]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG156]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast i8 addrspace(1)* [[TMP6]] to i8*, !dbg [[DBG156]] -// CHECK1-NEXT: store i8* [[TMP7]], i8** [[_TMP2]], align 8, !dbg [[DBG156]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG156]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META157:![0-9]+]], metadata !DIExpression()), !dbg [[DBG159:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 1, !dbg [[DBG160:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG160]] -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX3]], i64 0, i64 1, !dbg [[DBG160]] -// CHECK1-NEXT: store i32* [[ARRAYIDX4]], i32** [[F]], align 8, !dbg [[DBG159]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META161:![0-9]+]], metadata !DIExpression()), !dbg [[DBG162:![0-9]+]] -// CHECK1-NEXT: store i32* [[A_ADDR]], i32** [[G]], align 8, !dbg [[DBG162]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META163:![0-9]+]], metadata !DIExpression()), !dbg [[DBG164:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP5]], i64 0, i64 1, !dbg [[DBG165:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX5]], i64 0, i64 1, !dbg [[DBG165]] -// CHECK1-NEXT: store i32* [[ARRAYIDX6]], i32** [[H]], align 8, !dbg [[DBG164]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META166:![0-9]+]], metadata !DIExpression()), !dbg [[DBG167:![0-9]+]] -// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG167]] -// CHECK1-NEXT: store i32 5, i32* [[A_ADDR]], align 4, !dbg [[DBG168:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP5]], i64 0, i64 0, !dbg [[DBG169:![0-9]+]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG170:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP9]] to i64, !dbg [[DBG169]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX7]], i64 0, i64 [[IDXPROM]], !dbg [[DBG169]] -// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX8]], align 4, !dbg [[DBG171:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG172:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX9]], i64 0, i64 0, !dbg [[DBG172]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG173:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM11:%.*]] = sext i32 [[TMP10]] to i64, !dbg [[DBG172]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX10]], i64 0, i64 [[IDXPROM11]], !dbg [[DBG172]] -// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX12]], align 4, !dbg [[DBG174:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG175:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG175]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG176:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP11]] to i64, !dbg [[DBG175]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG175]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[ARRAYIDX16]], align 4, !dbg [[DBG175]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP5]], i64 0, i64 0, !dbg [[DBG177:![0-9]+]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG178:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG177]] -// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG177]] -// CHECK1-NEXT: store i32 [[TMP12]], i32* [[ARRAYIDX19]], align 4, !dbg [[DBG179:![0-9]+]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i8, i8* [[TMP8]], align 1, !dbg [[DBG180:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP14]] to i1, !dbg [[DBG180]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG180]] -// CHECK1-NEXT: store i32 [[CONV]], i32* [[D]], align 4, !dbg [[DBG181:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG182:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META169:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG171:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META157:![0-9]+]]), !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG171]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP5:%.*]] = call [10 x [10 x i32]] addrspace(1)* @llvm.noalias.p1a10a10i32.p0i8.p0p1a10a10i32.i64([10 x [10 x i32]] addrspace(1)* [[TMP4]], i8* null, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], i64 0, metadata [[META157]]), !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP5]] to [10 x [10 x i32]]*, !dbg [[DBG171]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP6]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP9:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP8]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META157]]), !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8 addrspace(1)* [[TMP9]] to i8*, !dbg [[DBG171]] +// CHECK1-NEXT: store i8* [[TMP10]], i8** [[_TMP2]], align 8, !dbg [[DBG171]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG171]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META172:![0-9]+]], metadata !DIExpression()), !dbg [[DBG174:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 1, !dbg [[DBG175:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG175]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX3]], i64 0, i64 1, !dbg [[DBG175]] +// CHECK1-NEXT: store i32* [[ARRAYIDX4]], i32** [[F]], align 8, !dbg [[DBG174]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META176:![0-9]+]], metadata !DIExpression()), !dbg [[DBG177:![0-9]+]] +// CHECK1-NEXT: store i32* [[A_ADDR]], i32** [[G]], align 8, !dbg [[DBG177]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META178:![0-9]+]], metadata !DIExpression()), !dbg [[DBG179:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP7]], i64 0, i64 1, !dbg [[DBG180:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX5]], i64 0, i64 1, !dbg [[DBG180]] +// CHECK1-NEXT: store i32* [[ARRAYIDX6]], i32** [[H]], align 8, !dbg [[DBG179]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META181:![0-9]+]], metadata !DIExpression()), !dbg [[DBG182:![0-9]+]] +// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG182]] +// CHECK1-NEXT: store i32 5, i32* [[A_ADDR]], align 4, !dbg [[DBG183:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP7]], i64 0, i64 0, !dbg [[DBG184:![0-9]+]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG185:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP12]] to i64, !dbg [[DBG184]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX7]], i64 0, i64 [[IDXPROM]], !dbg [[DBG184]] +// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX8]], align 4, !dbg [[DBG186:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG187:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX9]], i64 0, i64 0, !dbg [[DBG187]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG188:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM11:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG187]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX10]], i64 0, i64 [[IDXPROM11]], !dbg [[DBG187]] +// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX12]], align 4, !dbg [[DBG189:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG190:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG190]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG191:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP14]] to i64, !dbg [[DBG190]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG190]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[ARRAYIDX16]], align 4, !dbg [[DBG190]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP7]], i64 0, i64 0, !dbg [[DBG192:![0-9]+]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG193:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP16]] to i64, !dbg [[DBG192]] +// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG192]] +// CHECK1-NEXT: store i32 [[TMP15]], i32* [[ARRAYIDX19]], align 4, !dbg [[DBG194:![0-9]+]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i8, i8* [[TMP11]], align 1, !dbg [[DBG195:![0-9]+]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP17]] to i1, !dbg [[DBG195]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG195]] +// CHECK1-NEXT: store i32 [[CONV]], i32* [[D]], align 4, !dbg [[DBG196:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG197:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__2 -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG183:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG198:![0-9]+]] !noalias !199 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -437,66 +451,68 @@ // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META184:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META202:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META186:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META204:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META187:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META205:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203]] // CHECK1-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META188:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META206:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META189:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META207:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META190:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG191:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP5]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP7]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG191]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast i8* [[TMP8]] to i8 addrspace(1)*, !dbg [[DBG191]] -// CHECK1-NEXT: call void @__omp_outlined___debug__1(i32* [[TMP3]], i32* [[TMP4]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP9]], i32 [[TMP6]], [10 x [10 x i32]] addrspace(1)* [[TMP10]], i8 addrspace(1)* [[TMP11]]) #[[ATTR3]], !dbg [[DBG191]] -// CHECK1-NEXT: ret void, !dbg [[DBG191]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META208:![0-9]+]], metadata !DIExpression()), !dbg [[DBG203]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG209:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP4:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP3]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META199:![0-9]+]]), !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META199]]), !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP9:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP7]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP9]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG209]] +// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast i8* [[TMP10]] to i8 addrspace(1)*, !dbg [[DBG209]] +// CHECK1-NEXT: call void @__omp_outlined___debug__1(i32* [[TMP4]], i32* [[TMP6]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP11]], i32 [[TMP8]], [10 x [10 x i32]] addrspace(1)* [[TMP12]], i8 addrspace(1)* [[TMP13]]) #[[ATTR4]], !dbg [[DBG209]] +// CHECK1-NEXT: ret void, !dbg [[DBG209]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37 -// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR4]] !dbg [[DBG168:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR6]] !dbg [[DBG210:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]]*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META193:![0-9]+]], metadata !DIExpression()), !dbg [[DBG194:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META211:![0-9]+]], metadata !DIExpression()), !dbg [[DBG212:![0-9]+]] // CHECK1-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META195:![0-9]+]], metadata !DIExpression()), !dbg [[DBG194]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META213:![0-9]+]], metadata !DIExpression()), !dbg [[DBG212]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META196:![0-9]+]], metadata !DIExpression()), !dbg [[DBG194]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META214:![0-9]+]], metadata !DIExpression()), !dbg [[DBG212]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META197:![0-9]+]], metadata !DIExpression()), !dbg [[DBG194]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG198:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG198]] -// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG198]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG198]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG198]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG198]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG198]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG198]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP3]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG198]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP5]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG198]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8* [[TMP6]] to i8 addrspace(1)*, !dbg [[DBG198]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP7]], i32 [[TMP4]], [10 x [10 x i32]] addrspace(1)* [[TMP8]], i8 addrspace(1)* [[TMP9]]) #[[ATTR3]], !dbg [[DBG198]] -// CHECK1-NEXT: ret void, !dbg [[DBG198]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META215:![0-9]+]], metadata !DIExpression()), !dbg [[DBG212]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG216:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP3]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP5]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG216]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8* [[TMP6]] to i8 addrspace(1)*, !dbg [[DBG216]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l37_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP7]], i32 [[TMP4]], [10 x [10 x i32]] addrspace(1)* [[TMP8]], i8 addrspace(1)* [[TMP9]]) #[[ATTR4]], !dbg [[DBG216]] +// CHECK1-NEXT: ret void, !dbg [[DBG216]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51_debug__ -// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 addrspace(1)* noalias [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG199:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 addrspace(1)* noalias [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG217:![0-9]+]] !noalias !222 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]] addrspace(1)*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32 addrspace(1)*, align 8 @@ -508,55 +524,59 @@ // CHECK1-NEXT: [[_TMP3:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [4 x i8*], align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META204:![0-9]+]], metadata !DIExpression()), !dbg [[DBG205:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META225:![0-9]+]], metadata !DIExpression()), !dbg [[DBG226:![0-9]+]] // CHECK1-NEXT: store i32 addrspace(1)* [[A]], i32 addrspace(1)** [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32 addrspace(1)** [[A_ADDR]], metadata [[META206:![0-9]+]], metadata !DIExpression()), !dbg [[DBG207:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32 addrspace(1)** [[A_ADDR]], metadata [[META227:![0-9]+]], metadata !DIExpression()), !dbg [[DBG228:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]] addrspace(1)* [[B]], [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META208:![0-9]+]], metadata !DIExpression()), !dbg [[DBG209:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META229:![0-9]+]], metadata !DIExpression()), !dbg [[DBG230:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META210:![0-9]+]], metadata !DIExpression()), !dbg [[DBG211:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG212:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG212]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32 addrspace(1)*, i32 addrspace(1)** [[A_ADDR]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast i32 addrspace(1)* [[TMP3]] to i32*, !dbg [[DBG212]] -// CHECK1-NEXT: store i32* [[TMP4]], i32** [[_TMP1]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[_TMP1]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP6]] to [10 x [10 x i32]]*, !dbg [[DBG212]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP7]], [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8 addrspace(1)* [[TMP9]] to i8*, !dbg [[DBG212]] -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[_TMP3]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[_TMP3]], align 8, !dbg [[DBG212]] -// CHECK1-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB13:[0-9]+]], i8 2, i1 false, i1 true), !dbg [[DBG212]] -// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP12]], -1, !dbg [[DBG212]] -// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG212]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META231:![0-9]+]], metadata !DIExpression()), !dbg [[DBG232:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG233:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META222:![0-9]+]]), !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG233]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32 addrspace(1)*, i32 addrspace(1)** [[A_ADDR]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP5:%.*]] = call i32 addrspace(1)* @llvm.noalias.p1i32.p0i8.p0p1i32.i64(i32 addrspace(1)* [[TMP4]], i8* null, i32 addrspace(1)** [[A_ADDR]], i64 0, metadata [[META222]]), !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast i32 addrspace(1)* [[TMP5]] to i32*, !dbg [[DBG233]] +// CHECK1-NEXT: store i32* [[TMP6]], i32** [[_TMP1]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32*, i32** [[_TMP1]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP9:%.*]] = call [10 x [10 x i32]] addrspace(1)* @llvm.noalias.p1a10a10i32.p0i8.p0p1a10a10i32.i64([10 x [10 x i32]] addrspace(1)* [[TMP8]], i8* null, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], i64 0, metadata [[META222]]), !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP9]] to [10 x [10 x i32]]*, !dbg [[DBG233]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP10]], [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP11:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP13:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP12]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META222]]), !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP14:%.*]] = addrspacecast i8 addrspace(1)* [[TMP13]] to i8*, !dbg [[DBG233]] +// CHECK1-NEXT: store i8* [[TMP14]], i8** [[_TMP3]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i8*, i8** [[_TMP3]], align 8, !dbg [[DBG233]] +// CHECK1-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB13:[0-9]+]], i8 2, i1 false, i1 true), !dbg [[DBG233]] +// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP16]], -1, !dbg [[DBG233]] +// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG233]] // CHECK1: user_code.entry: -// CHECK1-NEXT: [[TMP13:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB15:[0-9]+]]) -// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG213:![0-9]+]] -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP2]] to i8*, !dbg [[DBG213]] -// CHECK1-NEXT: store i8* [[TMP15]], i8** [[TMP14]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP5]] to i8*, !dbg [[DBG213]] -// CHECK1-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP19:%.*]] = bitcast [10 x [10 x i32]]* [[TMP8]] to i8*, !dbg [[DBG213]] -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[TMP18]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG213]] -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[TMP20]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG213]] -// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB15]], i32 [[TMP13]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i32*, [10 x [10 x i32]]*, i8*)* @__omp_outlined__4 to i8*), i8* null, i8** [[TMP21]], i64 4), !dbg [[DBG213]] -// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB17:[0-9]+]], i8 2, i1 true), !dbg [[DBG214:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG216:![0-9]+]] +// CHECK1-NEXT: [[TMP17:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB15:[0-9]+]]) +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG234:![0-9]+]] +// CHECK1-NEXT: [[TMP19:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP3]] to i8*, !dbg [[DBG234]] +// CHECK1-NEXT: store i8* [[TMP19]], i8** [[TMP18]], align 8, !dbg [[DBG234]] +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG234]] +// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP7]] to i8*, !dbg [[DBG234]] +// CHECK1-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !dbg [[DBG234]] +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG234]] +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast [10 x [10 x i32]]* [[TMP11]] to i8*, !dbg [[DBG234]] +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !dbg [[DBG234]] +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG234]] +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[TMP24]], align 8, !dbg [[DBG234]] +// CHECK1-NEXT: [[TMP25:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG234]] +// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB15]], i32 [[TMP17]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i32*, [10 x [10 x i32]]*, i8*)* @__omp_outlined__4 to i8*), i8* null, i8** [[TMP25]], i64 4), !dbg [[DBG234]] +// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB17:[0-9]+]], i8 2, i1 true), !dbg [[DBG235:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG237:![0-9]+]] // CHECK1: worker.exit: -// CHECK1-NEXT: ret void, !dbg [[DBG212]] +// CHECK1-NEXT: ret void, !dbg [[DBG233]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined___debug__3 -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 addrspace(1)* noalias [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG217:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 addrspace(1)* noalias [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG238:![0-9]+]] !noalias !241 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -573,82 +593,86 @@ // CHECK1-NEXT: [[H:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META220:![0-9]+]], metadata !DIExpression()), !dbg [[DBG221:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META244:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META222:![0-9]+]], metadata !DIExpression()), !dbg [[DBG221]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META246:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META223:![0-9]+]], metadata !DIExpression()), !dbg [[DBG224:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META247:![0-9]+]], metadata !DIExpression()), !dbg [[DBG248:![0-9]+]] // CHECK1-NEXT: store i32 addrspace(1)* [[A]], i32 addrspace(1)** [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32 addrspace(1)** [[A_ADDR]], metadata [[META225:![0-9]+]], metadata !DIExpression()), !dbg [[DBG226:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32 addrspace(1)** [[A_ADDR]], metadata [[META249:![0-9]+]], metadata !DIExpression()), !dbg [[DBG250:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]] addrspace(1)* [[B]], [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META227:![0-9]+]], metadata !DIExpression()), !dbg [[DBG228:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META251:![0-9]+]], metadata !DIExpression()), !dbg [[DBG252:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META229:![0-9]+]], metadata !DIExpression()), !dbg [[DBG230:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG231:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG231]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32 addrspace(1)*, i32 addrspace(1)** [[A_ADDR]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast i32 addrspace(1)* [[TMP3]] to i32*, !dbg [[DBG231]] -// CHECK1-NEXT: store i32* [[TMP4]], i32** [[_TMP1]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[_TMP1]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP6]] to [10 x [10 x i32]]*, !dbg [[DBG231]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP7]], [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8 addrspace(1)* [[TMP9]] to i8*, !dbg [[DBG231]] -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[_TMP3]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[_TMP3]], align 8, !dbg [[DBG231]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META232:![0-9]+]], metadata !DIExpression()), !dbg [[DBG234:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 1, !dbg [[DBG235:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG235]] -// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX4]], i64 0, i64 1, !dbg [[DBG235]] -// CHECK1-NEXT: store i32* [[ARRAYIDX5]], i32** [[F]], align 8, !dbg [[DBG234]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META236:![0-9]+]], metadata !DIExpression()), !dbg [[DBG237:![0-9]+]] -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[G]], align 8, !dbg [[DBG237]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META238:![0-9]+]], metadata !DIExpression()), !dbg [[DBG239:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP8]], i64 0, i64 1, !dbg [[DBG240:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG240]] -// CHECK1-NEXT: store i32* [[ARRAYIDX7]], i32** [[H]], align 8, !dbg [[DBG239]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META241:![0-9]+]], metadata !DIExpression()), !dbg [[DBG242:![0-9]+]] -// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG242]] -// CHECK1-NEXT: store i32 5, i32* [[TMP5]], align 4, !dbg [[DBG243:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP8]], i64 0, i64 0, !dbg [[DBG244:![0-9]+]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG245:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP12]] to i64, !dbg [[DBG244]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX8]], i64 0, i64 [[IDXPROM]], !dbg [[DBG244]] -// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX9]], align 4, !dbg [[DBG246:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG247:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX10]], i64 0, i64 0, !dbg [[DBG247]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG248:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP13]] to i64, !dbg [[DBG247]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX11]], i64 0, i64 [[IDXPROM12]], !dbg [[DBG247]] -// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX13]], align 4, !dbg [[DBG249:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG250:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX14]], i64 0, i64 0, !dbg [[DBG250]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG251:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM16:%.*]] = sext i32 [[TMP14]] to i64, !dbg [[DBG250]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX15]], i64 0, i64 [[IDXPROM16]], !dbg [[DBG250]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[ARRAYIDX17]], align 4, !dbg [[DBG250]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP8]], i64 0, i64 0, !dbg [[DBG252:![0-9]+]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG253:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP16]] to i64, !dbg [[DBG252]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG252]] -// CHECK1-NEXT: store i32 [[TMP15]], i32* [[ARRAYIDX20]], align 4, !dbg [[DBG254:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP8]], i64 0, i64 0, !dbg [[DBG255:![0-9]+]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG256:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP17]] to i64, !dbg [[DBG255]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[ARRAYIDX23]], align 4, !dbg [[DBG255]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP18]], 0, !dbg [[DBG255]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG257:![0-9]+]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], i8* [[TMP11]], align 1, !dbg [[DBG257]] -// CHECK1-NEXT: ret void, !dbg [[DBG258:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META253:![0-9]+]], metadata !DIExpression()), !dbg [[DBG254:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG255:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META241:![0-9]+]]), !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG255]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32 addrspace(1)*, i32 addrspace(1)** [[A_ADDR]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP5:%.*]] = call i32 addrspace(1)* @llvm.noalias.p1i32.p0i8.p0p1i32.i64(i32 addrspace(1)* [[TMP4]], i8* null, i32 addrspace(1)** [[A_ADDR]], i64 0, metadata [[META241]]), !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast i32 addrspace(1)* [[TMP5]] to i32*, !dbg [[DBG255]] +// CHECK1-NEXT: store i32* [[TMP6]], i32** [[_TMP1]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32*, i32** [[_TMP1]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP9:%.*]] = call [10 x [10 x i32]] addrspace(1)* @llvm.noalias.p1a10a10i32.p0i8.p0p1a10a10i32.i64([10 x [10 x i32]] addrspace(1)* [[TMP8]], i8* null, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], i64 0, metadata [[META241]]), !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP9]] to [10 x [10 x i32]]*, !dbg [[DBG255]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP10]], [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP11:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP13:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP12]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META241]]), !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP14:%.*]] = addrspacecast i8 addrspace(1)* [[TMP13]] to i8*, !dbg [[DBG255]] +// CHECK1-NEXT: store i8* [[TMP14]], i8** [[_TMP3]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i8*, i8** [[_TMP3]], align 8, !dbg [[DBG255]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META256:![0-9]+]], metadata !DIExpression()), !dbg [[DBG258:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 1, !dbg [[DBG259:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG259]] +// CHECK1-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX4]], i64 0, i64 1, !dbg [[DBG259]] +// CHECK1-NEXT: store i32* [[ARRAYIDX5]], i32** [[F]], align 8, !dbg [[DBG258]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META260:![0-9]+]], metadata !DIExpression()), !dbg [[DBG261:![0-9]+]] +// CHECK1-NEXT: store i32* [[TMP7]], i32** [[G]], align 8, !dbg [[DBG261]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META262:![0-9]+]], metadata !DIExpression()), !dbg [[DBG263:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP11]], i64 0, i64 1, !dbg [[DBG264:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG264]] +// CHECK1-NEXT: store i32* [[ARRAYIDX7]], i32** [[H]], align 8, !dbg [[DBG263]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META265:![0-9]+]], metadata !DIExpression()), !dbg [[DBG266:![0-9]+]] +// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG266]] +// CHECK1-NEXT: store i32 5, i32* [[TMP7]], align 4, !dbg [[DBG267:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP11]], i64 0, i64 0, !dbg [[DBG268:![0-9]+]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG269:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP16]] to i64, !dbg [[DBG268]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX8]], i64 0, i64 [[IDXPROM]], !dbg [[DBG268]] +// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX9]], align 4, !dbg [[DBG270:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG271:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX10]], i64 0, i64 0, !dbg [[DBG271]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG272:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM12:%.*]] = sext i32 [[TMP17]] to i64, !dbg [[DBG271]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX11]], i64 0, i64 [[IDXPROM12]], !dbg [[DBG271]] +// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX13]], align 4, !dbg [[DBG273:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG274:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX14]], i64 0, i64 0, !dbg [[DBG274]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG275:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM16:%.*]] = sext i32 [[TMP18]] to i64, !dbg [[DBG274]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX15]], i64 0, i64 [[IDXPROM16]], !dbg [[DBG274]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[ARRAYIDX17]], align 4, !dbg [[DBG274]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP11]], i64 0, i64 0, !dbg [[DBG276:![0-9]+]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG277:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG276]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG276]] +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[ARRAYIDX20]], align 4, !dbg [[DBG278:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP11]], i64 0, i64 0, !dbg [[DBG279:![0-9]+]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG280:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP21]] to i64, !dbg [[DBG279]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[ARRAYIDX23]], align 4, !dbg [[DBG279]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP22]], 0, !dbg [[DBG279]] +// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG281:![0-9]+]] +// CHECK1-NEXT: store i8 [[FROMBOOL]], i8* [[TMP15]], align 1, !dbg [[DBG281]] +// CHECK1-NEXT: ret void, !dbg [[DBG282:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__4 -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG259:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG283:![0-9]+]] !noalias !286 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -657,62 +681,64 @@ // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META262:![0-9]+]], metadata !DIExpression()), !dbg [[DBG263:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META289:![0-9]+]], metadata !DIExpression()), !dbg [[DBG290:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META264:![0-9]+]], metadata !DIExpression()), !dbg [[DBG263]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META291:![0-9]+]], metadata !DIExpression()), !dbg [[DBG290]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META265:![0-9]+]], metadata !DIExpression()), !dbg [[DBG263]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META292:![0-9]+]], metadata !DIExpression()), !dbg [[DBG290]] // CHECK1-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META266:![0-9]+]], metadata !DIExpression()), !dbg [[DBG263]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META293:![0-9]+]], metadata !DIExpression()), !dbg [[DBG290]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META267:![0-9]+]], metadata !DIExpression()), !dbg [[DBG263]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META294:![0-9]+]], metadata !DIExpression()), !dbg [[DBG290]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META268:![0-9]+]], metadata !DIExpression()), !dbg [[DBG263]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG269:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP6]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast i32* [[TMP7]] to i32 addrspace(1)*, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP8]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG269]] -// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast i8* [[TMP9]] to i8 addrspace(1)*, !dbg [[DBG269]] -// CHECK1-NEXT: call void @__omp_outlined___debug__3(i32* [[TMP4]], i32* [[TMP5]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP10]], i32 addrspace(1)* [[TMP11]], [10 x [10 x i32]] addrspace(1)* [[TMP12]], i8 addrspace(1)* [[TMP13]]) #[[ATTR3]], !dbg [[DBG269]] -// CHECK1-NEXT: ret void, !dbg [[DBG269]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META295:![0-9]+]], metadata !DIExpression()), !dbg [[DBG290]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG296:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP5:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP4]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META286:![0-9]+]]), !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP7:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP6]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META286]]), !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP10:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP8]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast i32* [[TMP9]] to i32 addrspace(1)*, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP14:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP10]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG296]] +// CHECK1-NEXT: [[TMP15:%.*]] = addrspacecast i8* [[TMP11]] to i8 addrspace(1)*, !dbg [[DBG296]] +// CHECK1-NEXT: call void @__omp_outlined___debug__3(i32* [[TMP5]], i32* [[TMP7]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP12]], i32 addrspace(1)* [[TMP13]], [10 x [10 x i32]] addrspace(1)* [[TMP14]], i8 addrspace(1)* [[TMP15]]) #[[ATTR4]], !dbg [[DBG296]] +// CHECK1-NEXT: ret void, !dbg [[DBG296]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51 -// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR4]] !dbg [[DBG232:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR6]] !dbg [[DBG297:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]]*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META273:![0-9]+]], metadata !DIExpression()), !dbg [[DBG274:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META300:![0-9]+]], metadata !DIExpression()), !dbg [[DBG301:![0-9]+]] // CHECK1-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META275:![0-9]+]], metadata !DIExpression()), !dbg [[DBG274]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META302:![0-9]+]], metadata !DIExpression()), !dbg [[DBG301]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META276:![0-9]+]], metadata !DIExpression()), !dbg [[DBG274]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META303:![0-9]+]], metadata !DIExpression()), !dbg [[DBG301]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META277:![0-9]+]], metadata !DIExpression()), !dbg [[DBG274]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG278:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP4]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i32* [[TMP5]] to i32 addrspace(1)*, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP6]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG278]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast i8* [[TMP7]] to i8 addrspace(1)*, !dbg [[DBG278]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP8]], i32 addrspace(1)* [[TMP9]], [10 x [10 x i32]] addrspace(1)* [[TMP10]], i8 addrspace(1)* [[TMP11]]) #[[ATTR3]], !dbg [[DBG278]] -// CHECK1-NEXT: ret void, !dbg [[DBG278]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META304:![0-9]+]], metadata !DIExpression()), !dbg [[DBG301]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG305:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP4]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i32* [[TMP5]] to i32 addrspace(1)*, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP6]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG305]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast i8* [[TMP7]] to i8 addrspace(1)*, !dbg [[DBG305]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l51_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP8]], i32 addrspace(1)* [[TMP9]], [10 x [10 x i32]] addrspace(1)* [[TMP10]], i8 addrspace(1)* [[TMP11]]) #[[ATTR4]], !dbg [[DBG305]] +// CHECK1-NEXT: ret void, !dbg [[DBG305]] // Index: clang/test/OpenMP/target_parallel_for_codegen.cpp =================================================================== --- clang/test/OpenMP/target_parallel_for_codegen.cpp +++ clang/test/OpenMP/target_parallel_for_codegen.cpp @@ -1042,47 +1042,51 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP25:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK1-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 -// CHECK1-NEXT: br i1 [[TMP26]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META22]]), !noalias !18 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META23]]), !noalias !18 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META24]]), !noalias !18 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !18 +// CHECK1-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP33:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !18 +// CHECK1-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 +// CHECK1-NEXT: br i1 [[TMP34]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK1: omp_offload.failed.i: -// CHECK1-NEXT: [[TMP27:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK1-NEXT: [[TMP35:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !18 // CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK1-NEXT: store i16 [[TMP27]], i16* [[CONV_I]], align 2, !noalias !24 -// CHECK1-NEXT: [[TMP28:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK1-NEXT: store i16 [[TMP35]], i16* [[CONV_I]], align 2, !noalias !18 +// CHECK1-NEXT: [[TMP36:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 // CHECK1-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[LIN_CASTED_I]] to i32* -// CHECK1-NEXT: store i32 [[TMP29]], i32* [[CONV4_I]], align 4, !noalias !24 -// CHECK1-NEXT: [[TMP30:%.*]] = load i64, i64* [[LIN_CASTED_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK1-NEXT: store i32 [[TMP37]], i32* [[CONV4_I]], align 4, !noalias !18 +// CHECK1-NEXT: [[TMP38:%.*]] = load i64, i64* [[LIN_CASTED_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 // CHECK1-NEXT: [[CONV5_I:%.*]] = bitcast i64* [[A_CASTED_I]] to i32* -// CHECK1-NEXT: store i32 [[TMP31]], i32* [[CONV5_I]], align 4, !noalias !24 -// CHECK1-NEXT: [[TMP32:%.*]] = load i64, i64* [[A_CASTED_I]], align 8, !noalias !24 -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i64 [[TMP28]], i64 [[TMP30]], i64 [[TMP32]]) #[[ATTR4]] +// CHECK1-NEXT: store i32 [[TMP39]], i32* [[CONV5_I]], align 4, !noalias !18 +// CHECK1-NEXT: [[TMP40:%.*]] = load i64, i64* [[A_CASTED_I]], align 8, !noalias !18 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i64 [[TMP36]], i64 [[TMP38]], i64 [[TMP40]]) #[[ATTR4]], !noalias !18 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK1: .omp_outlined..3.exit: // CHECK1-NEXT: ret i32 0 @@ -2691,47 +2695,51 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP25:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK2-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 -// CHECK2-NEXT: br i1 [[TMP26]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META22]]), !noalias !18 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META23]]), !noalias !18 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META24]]), !noalias !18 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !18 +// CHECK2-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP33:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !18 +// CHECK2-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 +// CHECK2-NEXT: br i1 [[TMP34]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK2: omp_offload.failed.i: -// CHECK2-NEXT: [[TMP27:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK2-NEXT: [[TMP35:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !18 // CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK2-NEXT: store i16 [[TMP27]], i16* [[CONV_I]], align 2, !noalias !24 -// CHECK2-NEXT: [[TMP28:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK2-NEXT: store i16 [[TMP35]], i16* [[CONV_I]], align 2, !noalias !18 +// CHECK2-NEXT: [[TMP36:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 // CHECK2-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[LIN_CASTED_I]] to i32* -// CHECK2-NEXT: store i32 [[TMP29]], i32* [[CONV4_I]], align 4, !noalias !24 -// CHECK2-NEXT: [[TMP30:%.*]] = load i64, i64* [[LIN_CASTED_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK2-NEXT: store i32 [[TMP37]], i32* [[CONV4_I]], align 4, !noalias !18 +// CHECK2-NEXT: [[TMP38:%.*]] = load i64, i64* [[LIN_CASTED_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 // CHECK2-NEXT: [[CONV5_I:%.*]] = bitcast i64* [[A_CASTED_I]] to i32* -// CHECK2-NEXT: store i32 [[TMP31]], i32* [[CONV5_I]], align 4, !noalias !24 -// CHECK2-NEXT: [[TMP32:%.*]] = load i64, i64* [[A_CASTED_I]], align 8, !noalias !24 -// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i64 [[TMP28]], i64 [[TMP30]], i64 [[TMP32]]) #[[ATTR4]] +// CHECK2-NEXT: store i32 [[TMP39]], i32* [[CONV5_I]], align 4, !noalias !18 +// CHECK2-NEXT: [[TMP40:%.*]] = load i64, i64* [[A_CASTED_I]], align 8, !noalias !18 +// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i64 [[TMP36]], i64 [[TMP38]], i64 [[TMP40]]) #[[ATTR4]], !noalias !18 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK2: .omp_outlined..3.exit: // CHECK2-NEXT: ret i32 0 @@ -4319,45 +4327,49 @@ // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK3-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK3-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK3-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP25:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK3-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 -// CHECK3-NEXT: br i1 [[TMP26]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK3-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK3-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK3-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK3-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META24]]), !noalias !19 +// CHECK3-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK3-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META25]]), !noalias !19 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK3-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !19 +// CHECK3-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK3-NEXT: [[TMP33:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !19 +// CHECK3-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 +// CHECK3-NEXT: br i1 [[TMP34]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK3: omp_offload.failed.i: -// CHECK3-NEXT: [[TMP27:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK3-NEXT: [[TMP35:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !19 // CHECK3-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK3-NEXT: store i16 [[TMP27]], i16* [[CONV_I]], align 2, !noalias !25 -// CHECK3-NEXT: [[TMP28:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK3-NEXT: store i32 [[TMP29]], i32* [[LIN_CASTED_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[LIN_CASTED_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK3-NEXT: store i32 [[TMP31]], i32* [[A_CASTED_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[A_CASTED_I]], align 4, !noalias !25 -// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i32 [[TMP28]], i32 [[TMP30]], i32 [[TMP32]]) #[[ATTR4]] +// CHECK3-NEXT: store i16 [[TMP35]], i16* [[CONV_I]], align 2, !noalias !19 +// CHECK3-NEXT: [[TMP36:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK3-NEXT: store i32 [[TMP37]], i32* [[LIN_CASTED_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[LIN_CASTED_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK3-NEXT: store i32 [[TMP39]], i32* [[A_CASTED_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, i32* [[A_CASTED_I]], align 4, !noalias !19 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i32 [[TMP36]], i32 [[TMP38]], i32 [[TMP40]]) #[[ATTR4]], !noalias !19 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK3: .omp_outlined..3.exit: // CHECK3-NEXT: ret i32 0 @@ -5924,45 +5936,49 @@ // CHECK4-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK4-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK4-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK4-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP25:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK4-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 -// CHECK4-NEXT: br i1 [[TMP26]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK4-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK4-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK4-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK4-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META24]]), !noalias !19 +// CHECK4-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK4-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META25]]), !noalias !19 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK4-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !19 +// CHECK4-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK4-NEXT: [[TMP33:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !19 +// CHECK4-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 +// CHECK4-NEXT: br i1 [[TMP34]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK4: omp_offload.failed.i: -// CHECK4-NEXT: [[TMP27:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK4-NEXT: [[TMP35:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !19 // CHECK4-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK4-NEXT: store i16 [[TMP27]], i16* [[CONV_I]], align 2, !noalias !25 -// CHECK4-NEXT: [[TMP28:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK4-NEXT: store i32 [[TMP29]], i32* [[LIN_CASTED_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP30:%.*]] = load i32, i32* [[LIN_CASTED_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK4-NEXT: store i32 [[TMP31]], i32* [[A_CASTED_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP32:%.*]] = load i32, i32* [[A_CASTED_I]], align 4, !noalias !25 -// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i32 [[TMP28]], i32 [[TMP30]], i32 [[TMP32]]) #[[ATTR4]] +// CHECK4-NEXT: store i16 [[TMP35]], i16* [[CONV_I]], align 2, !noalias !19 +// CHECK4-NEXT: [[TMP36:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK4-NEXT: store i32 [[TMP37]], i32* [[LIN_CASTED_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP38:%.*]] = load i32, i32* [[LIN_CASTED_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK4-NEXT: store i32 [[TMP39]], i32* [[A_CASTED_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP40:%.*]] = load i32, i32* [[A_CASTED_I]], align 4, !noalias !19 +// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i32 [[TMP36]], i32 [[TMP38]], i32 [[TMP40]]) #[[ATTR4]], !noalias !19 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK4: .omp_outlined..3.exit: // CHECK4-NEXT: ret i32 0 @@ -10758,47 +10774,51 @@ // CHECK17-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK17-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK17-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK17-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK17-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK17-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK17-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK17-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK17-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK17-NEXT: [[TMP25:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK17-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 -// CHECK17-NEXT: br i1 [[TMP26]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK17-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK17-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK17-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK17-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META22]]), !noalias !18 +// CHECK17-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK17-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META23]]), !noalias !18 +// CHECK17-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK17-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META24]]), !noalias !18 +// CHECK17-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK17-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK17-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !18 +// CHECK17-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK17-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK17-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK17-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK17-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK17-NEXT: [[TMP33:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !18 +// CHECK17-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 +// CHECK17-NEXT: br i1 [[TMP34]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK17: omp_offload.failed.i: -// CHECK17-NEXT: [[TMP27:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK17-NEXT: [[TMP35:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !18 // CHECK17-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK17-NEXT: store i16 [[TMP27]], i16* [[CONV_I]], align 2, !noalias !24 -// CHECK17-NEXT: [[TMP28:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK17-NEXT: store i16 [[TMP35]], i16* [[CONV_I]], align 2, !noalias !18 +// CHECK17-NEXT: [[TMP36:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 // CHECK17-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[LIN_CASTED_I]] to i32* -// CHECK17-NEXT: store i32 [[TMP29]], i32* [[CONV4_I]], align 4, !noalias !24 -// CHECK17-NEXT: [[TMP30:%.*]] = load i64, i64* [[LIN_CASTED_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK17-NEXT: store i32 [[TMP37]], i32* [[CONV4_I]], align 4, !noalias !18 +// CHECK17-NEXT: [[TMP38:%.*]] = load i64, i64* [[LIN_CASTED_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 // CHECK17-NEXT: [[CONV5_I:%.*]] = bitcast i64* [[A_CASTED_I]] to i32* -// CHECK17-NEXT: store i32 [[TMP31]], i32* [[CONV5_I]], align 4, !noalias !24 -// CHECK17-NEXT: [[TMP32:%.*]] = load i64, i64* [[A_CASTED_I]], align 8, !noalias !24 -// CHECK17-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i64 [[TMP28]], i64 [[TMP30]], i64 [[TMP32]]) #[[ATTR4]] +// CHECK17-NEXT: store i32 [[TMP39]], i32* [[CONV5_I]], align 4, !noalias !18 +// CHECK17-NEXT: [[TMP40:%.*]] = load i64, i64* [[A_CASTED_I]], align 8, !noalias !18 +// CHECK17-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i64 [[TMP36]], i64 [[TMP38]], i64 [[TMP40]]) #[[ATTR4]], !noalias !18 // CHECK17-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK17: .omp_outlined..3.exit: // CHECK17-NEXT: ret i32 0 @@ -12407,47 +12427,51 @@ // CHECK18-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK18-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK18-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK18-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK18-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK18-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK18-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK18-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK18-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK18-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK18-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK18-NEXT: [[TMP25:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK18-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 -// CHECK18-NEXT: br i1 [[TMP26]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK18-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK18-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK18-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK18-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META22]]), !noalias !18 +// CHECK18-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK18-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META23]]), !noalias !18 +// CHECK18-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK18-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META24]]), !noalias !18 +// CHECK18-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK18-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK18-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !18 +// CHECK18-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK18-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK18-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK18-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK18-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK18-NEXT: [[TMP33:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !18 +// CHECK18-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 +// CHECK18-NEXT: br i1 [[TMP34]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK18: omp_offload.failed.i: -// CHECK18-NEXT: [[TMP27:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK18-NEXT: [[TMP35:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !18 // CHECK18-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK18-NEXT: store i16 [[TMP27]], i16* [[CONV_I]], align 2, !noalias !24 -// CHECK18-NEXT: [[TMP28:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK18-NEXT: store i16 [[TMP35]], i16* [[CONV_I]], align 2, !noalias !18 +// CHECK18-NEXT: [[TMP36:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 // CHECK18-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[LIN_CASTED_I]] to i32* -// CHECK18-NEXT: store i32 [[TMP29]], i32* [[CONV4_I]], align 4, !noalias !24 -// CHECK18-NEXT: [[TMP30:%.*]] = load i64, i64* [[LIN_CASTED_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK18-NEXT: store i32 [[TMP37]], i32* [[CONV4_I]], align 4, !noalias !18 +// CHECK18-NEXT: [[TMP38:%.*]] = load i64, i64* [[LIN_CASTED_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 // CHECK18-NEXT: [[CONV5_I:%.*]] = bitcast i64* [[A_CASTED_I]] to i32* -// CHECK18-NEXT: store i32 [[TMP31]], i32* [[CONV5_I]], align 4, !noalias !24 -// CHECK18-NEXT: [[TMP32:%.*]] = load i64, i64* [[A_CASTED_I]], align 8, !noalias !24 -// CHECK18-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i64 [[TMP28]], i64 [[TMP30]], i64 [[TMP32]]) #[[ATTR4]] +// CHECK18-NEXT: store i32 [[TMP39]], i32* [[CONV5_I]], align 4, !noalias !18 +// CHECK18-NEXT: [[TMP40:%.*]] = load i64, i64* [[A_CASTED_I]], align 8, !noalias !18 +// CHECK18-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i64 [[TMP36]], i64 [[TMP38]], i64 [[TMP40]]) #[[ATTR4]], !noalias !18 // CHECK18-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK18: .omp_outlined..3.exit: // CHECK18-NEXT: ret i32 0 @@ -14035,45 +14059,49 @@ // CHECK19-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK19-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK19-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK19-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK19-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK19-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK19-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK19-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK19-NEXT: [[TMP25:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK19-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 -// CHECK19-NEXT: br i1 [[TMP26]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK19-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK19-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK19-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK19-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK19-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK19-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META24]]), !noalias !19 +// CHECK19-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK19-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META25]]), !noalias !19 +// CHECK19-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK19-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !19 +// CHECK19-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK19-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK19-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK19-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK19-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK19-NEXT: [[TMP33:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !19 +// CHECK19-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 +// CHECK19-NEXT: br i1 [[TMP34]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK19: omp_offload.failed.i: -// CHECK19-NEXT: [[TMP27:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK19-NEXT: [[TMP35:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !19 // CHECK19-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK19-NEXT: store i16 [[TMP27]], i16* [[CONV_I]], align 2, !noalias !25 -// CHECK19-NEXT: [[TMP28:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK19-NEXT: store i32 [[TMP29]], i32* [[LIN_CASTED_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP30:%.*]] = load i32, i32* [[LIN_CASTED_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK19-NEXT: store i32 [[TMP31]], i32* [[A_CASTED_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP32:%.*]] = load i32, i32* [[A_CASTED_I]], align 4, !noalias !25 -// CHECK19-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i32 [[TMP28]], i32 [[TMP30]], i32 [[TMP32]]) #[[ATTR4]] +// CHECK19-NEXT: store i16 [[TMP35]], i16* [[CONV_I]], align 2, !noalias !19 +// CHECK19-NEXT: [[TMP36:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK19-NEXT: store i32 [[TMP37]], i32* [[LIN_CASTED_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP38:%.*]] = load i32, i32* [[LIN_CASTED_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK19-NEXT: store i32 [[TMP39]], i32* [[A_CASTED_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP40:%.*]] = load i32, i32* [[A_CASTED_I]], align 4, !noalias !19 +// CHECK19-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i32 [[TMP36]], i32 [[TMP38]], i32 [[TMP40]]) #[[ATTR4]], !noalias !19 // CHECK19-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK19: .omp_outlined..3.exit: // CHECK19-NEXT: ret i32 0 @@ -15640,45 +15668,49 @@ // CHECK20-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK20-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK20-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK20-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK20-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK20-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK20-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK20-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK20-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK20-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK20-NEXT: [[TMP25:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK20-NEXT: [[TMP26:%.*]] = icmp ne i32 [[TMP25]], 0 -// CHECK20-NEXT: br i1 [[TMP26]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] +// CHECK20-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK20-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK20-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK20-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK20-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK20-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META24]]), !noalias !19 +// CHECK20-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK20-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META25]]), !noalias !19 +// CHECK20-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK20-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !19 +// CHECK20-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK20-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK20-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK20-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK20-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK20-NEXT: [[TMP33:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !19 +// CHECK20-NEXT: [[TMP34:%.*]] = icmp ne i32 [[TMP33]], 0 +// CHECK20-NEXT: br i1 [[TMP34]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK20: omp_offload.failed.i: -// CHECK20-NEXT: [[TMP27:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK20-NEXT: [[TMP35:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !19 // CHECK20-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK20-NEXT: store i16 [[TMP27]], i16* [[CONV_I]], align 2, !noalias !25 -// CHECK20-NEXT: [[TMP28:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK20-NEXT: store i32 [[TMP29]], i32* [[LIN_CASTED_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP30:%.*]] = load i32, i32* [[LIN_CASTED_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK20-NEXT: store i32 [[TMP31]], i32* [[A_CASTED_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP32:%.*]] = load i32, i32* [[A_CASTED_I]], align 4, !noalias !25 -// CHECK20-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i32 [[TMP28]], i32 [[TMP30]], i32 [[TMP32]]) #[[ATTR4]] +// CHECK20-NEXT: store i16 [[TMP35]], i16* [[CONV_I]], align 2, !noalias !19 +// CHECK20-NEXT: [[TMP36:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK20-NEXT: store i32 [[TMP37]], i32* [[LIN_CASTED_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP38:%.*]] = load i32, i32* [[LIN_CASTED_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK20-NEXT: store i32 [[TMP39]], i32* [[A_CASTED_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP40:%.*]] = load i32, i32* [[A_CASTED_I]], align 4, !noalias !19 +// CHECK20-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l138(i32 [[TMP36]], i32 [[TMP38]], i32 [[TMP40]]) #[[ATTR4]], !noalias !19 // CHECK20-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK20: .omp_outlined..3.exit: // CHECK20-NEXT: ret i32 0 Index: clang/test/OpenMP/target_parallel_for_debug_codegen.cpp =================================================================== --- clang/test/OpenMP/target_parallel_for_debug_codegen.cpp +++ clang/test/OpenMP/target_parallel_for_debug_codegen.cpp @@ -55,7 +55,7 @@ return 0; } // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug__ -// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]]* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]], i1 zeroext [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR0:[0-9]+]] !dbg [[DBG14:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]]* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]], i1 zeroext [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR0:[0-9]+]] !dbg [[DBG13:![0-9]+]] !noalias !31 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]] addrspace(1)*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 @@ -68,60 +68,63 @@ // CHECK1-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [4 x i8*], align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META31:![0-9]+]], metadata !DIExpression()), !dbg [[DBG32:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META34:![0-9]+]], metadata !DIExpression()), !dbg [[DBG35:![0-9]+]] // CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META33:![0-9]+]], metadata !DIExpression()), !dbg [[DBG34:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META36:![0-9]+]], metadata !DIExpression()), !dbg [[DBG37:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META35:![0-9]+]], metadata !DIExpression()), !dbg [[DBG36:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META38:![0-9]+]], metadata !DIExpression()), !dbg [[DBG39:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META37:![0-9]+]], metadata !DIExpression()), !dbg [[DBG38:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META40:![0-9]+]], metadata !DIExpression()), !dbg [[DBG41:![0-9]+]] // CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[DOTCAPTURE_EXPR_]] to i8 // CHECK1-NEXT: store i8 [[FROMBOOL]], i8* [[DOTCAPTURE_EXPR__ADDR]], align 1 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8* [[DOTCAPTURE_EXPR__ADDR]], metadata [[META39:![0-9]+]], metadata !DIExpression()), !dbg [[DBG40:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG41:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG41]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG41]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG41]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG41]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP3]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG41]] -// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG41]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG41]] -// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast i8 addrspace(1)* [[TMP5]] to i8*, !dbg [[DBG41]] -// CHECK1-NEXT: store i8* [[TMP6]], i8** [[_TMP2]], align 8, !dbg [[DBG41]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG41]] -// CHECK1-NEXT: [[TMP8:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i8 2, i1 false, i1 false), !dbg [[DBG41]] -// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP8]], -1, !dbg [[DBG41]] -// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG41]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8* [[DOTCAPTURE_EXPR__ADDR]], metadata [[META42:![0-9]+]], metadata !DIExpression()), !dbg [[DBG43:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG44:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META31:![0-9]+]]), !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG44]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP5:%.*]] = call [10 x [10 x i32]]* @llvm.noalias.p0a10a10i32.p0i8.p0p0a10a10i32.i64([10 x [10 x i32]]* [[TMP4]], i8* null, [10 x [10 x i32]]** [[B_ADDR]], i64 0, metadata [[META31]]), !dbg [[DBG44]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP5]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP8:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP7]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META31]]), !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8 addrspace(1)* [[TMP8]] to i8*, !dbg [[DBG44]] +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[_TMP2]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG44]] +// CHECK1-NEXT: [[TMP11:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1:[0-9]+]], i8 2, i1 false, i1 false), !dbg [[DBG44]] +// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP11]], -1, !dbg [[DBG44]] +// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG44]] // CHECK1: user_code.entry: -// CHECK1-NEXT: [[TMP9:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB6:[0-9]+]]) -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG42:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG42]] -// CHECK1-NEXT: store i32 [[TMP10]], i32* [[CONV]], align 4, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP13:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP2]] to i8*, !dbg [[DBG42]] -// CHECK1-NEXT: store i8* [[TMP13]], i8** [[TMP12]], align 8, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP15:%.*]] = inttoptr i64 [[TMP11]] to i8*, !dbg [[DBG42]] -// CHECK1-NEXT: store i8* [[TMP15]], i8** [[TMP14]], align 8, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast [10 x [10 x i32]]* [[TMP4]] to i8*, !dbg [[DBG42]] -// CHECK1-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG42]] -// CHECK1-NEXT: store i8* [[TMP7]], i8** [[TMP18]], align 8, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP19:%.*]] = load i8, i8* [[DOTCAPTURE_EXPR__ADDR]], align 1, !dbg [[DBG43:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP19]] to i1, !dbg [[DBG43]] -// CHECK1-NEXT: [[TMP20:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG42]] -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG42]] -// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB6]], i32 [[TMP9]], i32 [[TMP20]], i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i64, [10 x [10 x i32]]*, i8*)* @__omp_outlined__ to i8*), i8* null, i8** [[TMP21]], i64 4), !dbg [[DBG42]] -// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB8:[0-9]+]], i8 2, i1 false), !dbg [[DBG45:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG46:![0-9]+]] +// CHECK1-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB6:[0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG45:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG45]] +// CHECK1-NEXT: store i32 [[TMP13]], i32* [[CONV]], align 4, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP16:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP3]] to i8*, !dbg [[DBG45]] +// CHECK1-NEXT: store i8* [[TMP16]], i8** [[TMP15]], align 8, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP18:%.*]] = inttoptr i64 [[TMP14]] to i8*, !dbg [[DBG45]] +// CHECK1-NEXT: store i8* [[TMP18]], i8** [[TMP17]], align 8, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP20:%.*]] = bitcast [10 x [10 x i32]]* [[TMP6]] to i8*, !dbg [[DBG45]] +// CHECK1-NEXT: store i8* [[TMP20]], i8** [[TMP19]], align 8, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG45]] +// CHECK1-NEXT: store i8* [[TMP10]], i8** [[TMP21]], align 8, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i8, i8* [[DOTCAPTURE_EXPR__ADDR]], align 1, !dbg [[DBG46:![0-9]+]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP22]] to i1, !dbg [[DBG46]] +// CHECK1-NEXT: [[TMP23:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG45]] +// CHECK1-NEXT: [[TMP24:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG45]] +// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB6]], i32 [[TMP12]], i32 [[TMP23]], i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i64, [10 x [10 x i32]]*, i8*)* @__omp_outlined__ to i8*), i8* null, i8** [[TMP24]], i64 4), !dbg [[DBG45]] +// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB8:[0-9]+]], i8 2, i1 false), !dbg [[DBG48:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG49:![0-9]+]] // CHECK1: worker.exit: -// CHECK1-NEXT: ret void, !dbg [[DBG41]] +// CHECK1-NEXT: ret void, !dbg [[DBG44]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined___debug__ -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]]* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG47:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]]* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG50:![0-9]+]] !noalias !57 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -145,151 +148,154 @@ // CHECK1-NEXT: [[H:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META54:![0-9]+]], metadata !DIExpression()), !dbg [[DBG55:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META60:![0-9]+]], metadata !DIExpression()), !dbg [[DBG61:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META56:![0-9]+]], metadata !DIExpression()), !dbg [[DBG55]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META62:![0-9]+]], metadata !DIExpression()), !dbg [[DBG61]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META57:![0-9]+]], metadata !DIExpression()), !dbg [[DBG58:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META63:![0-9]+]], metadata !DIExpression()), !dbg [[DBG64:![0-9]+]] // CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META59:![0-9]+]], metadata !DIExpression()), !dbg [[DBG60:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META65:![0-9]+]], metadata !DIExpression()), !dbg [[DBG66:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META61:![0-9]+]], metadata !DIExpression()), !dbg [[DBG62:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META67:![0-9]+]], metadata !DIExpression()), !dbg [[DBG68:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META63:![0-9]+]], metadata !DIExpression()), !dbg [[DBG64:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG65:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG65]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG65]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG65]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG65]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP3]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG65]] -// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG65]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG65]] -// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast i8 addrspace(1)* [[TMP5]] to i8*, !dbg [[DBG65]] -// CHECK1-NEXT: store i8* [[TMP6]], i8** [[_TMP2]], align 8, !dbg [[DBG65]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG65]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IV]], metadata [[META66:![0-9]+]], metadata !DIExpression()), !dbg [[DBG55]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_LB]], metadata [[META67:![0-9]+]], metadata !DIExpression()), !dbg [[DBG55]] -// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG68:![0-9]+]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_UB]], metadata [[META69:![0-9]+]], metadata !DIExpression()), !dbg [[DBG55]] -// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_STRIDE]], metadata [[META70:![0-9]+]], metadata !DIExpression()), !dbg [[DBG55]] -// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IS_LAST]], metadata [[META71:![0-9]+]], metadata !DIExpression()), !dbg [[DBG55]] -// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]* [[B4]], metadata [[META72:![0-9]+]], metadata !DIExpression()), !dbg [[DBG55]] -// CHECK1-NEXT: [[TMP8:%.*]] = bitcast [10 x [10 x i32]]* [[B4]] to i8*, !dbg [[DBG65]] -// CHECK1-NEXT: [[TMP9:%.*]] = bitcast [10 x [10 x i32]]* [[TMP4]] to i8*, !dbg [[DBG65]] -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP8]], i8* align 4 [[TMP9]], i64 400, i1 false), !dbg [[DBG65]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META73:![0-9]+]], metadata !DIExpression()), !dbg [[DBG55]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG65]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[TMP10]], align 4, !dbg [[DBG65]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP11]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG74:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG65]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META69:![0-9]+]], metadata !DIExpression()), !dbg [[DBG70:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG71:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META57:![0-9]+]]), !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG71]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP5:%.*]] = call [10 x [10 x i32]]* @llvm.noalias.p0a10a10i32.p0i8.p0p0a10a10i32.i64([10 x [10 x i32]]* [[TMP4]], i8* null, [10 x [10 x i32]]** [[B_ADDR]], i64 0, metadata [[META57]]), !dbg [[DBG71]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP5]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP8:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP7]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META57]]), !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8 addrspace(1)* [[TMP8]] to i8*, !dbg [[DBG71]] +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[_TMP2]], align 8, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG71]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IV]], metadata [[META72:![0-9]+]], metadata !DIExpression()), !dbg [[DBG61]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_LB]], metadata [[META73:![0-9]+]], metadata !DIExpression()), !dbg [[DBG61]] +// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG74:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_UB]], metadata [[META75:![0-9]+]], metadata !DIExpression()), !dbg [[DBG61]] +// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_STRIDE]], metadata [[META76:![0-9]+]], metadata !DIExpression()), !dbg [[DBG61]] +// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IS_LAST]], metadata [[META77:![0-9]+]], metadata !DIExpression()), !dbg [[DBG61]] +// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]* [[B4]], metadata [[META78:![0-9]+]], metadata !DIExpression()), !dbg [[DBG61]] +// CHECK1-NEXT: [[TMP11:%.*]] = bitcast [10 x [10 x i32]]* [[B4]] to i8*, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP12:%.*]] = bitcast [10 x [10 x i32]]* [[TMP6]] to i8*, !dbg [[DBG71]] +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP11]], i8* align 4 [[TMP12]], i64 400, i1 false), !dbg [[DBG71]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META79:![0-9]+]], metadata !DIExpression()), !dbg [[DBG61]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], align 4, !dbg [[DBG71]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB3:[0-9]+]], i32 [[TMP14]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG80:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG71]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP12]], 9, !dbg [[DBG68]] -// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG68]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP15]], 9, !dbg [[DBG74]] +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG74]] // CHECK1: cond.true: -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG68]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG74]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG68]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG74]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP13]], [[COND_FALSE]] ], !dbg [[DBG68]] -// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: store i32 [[TMP14]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP15]], [[TMP16]], !dbg [[DBG65]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG65]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP16]], [[COND_FALSE]] ], !dbg [[DBG74]] +// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: store i32 [[TMP17]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]], !dbg [[DBG71]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG71]] // CHECK1: omp.dispatch.body: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG65]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG71]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]], !dbg [[DBG65]] -// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG65]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP20]], [[TMP21]], !dbg [[DBG71]] +// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG71]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP19]], 1, !dbg [[DBG75:![0-9]+]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG75]] -// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4, !dbg [[DBG75]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META76:![0-9]+]], metadata !DIExpression()), !dbg [[DBG79:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 1, !dbg [[DBG80:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG80]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG80]] -// CHECK1-NEXT: store i32* [[ARRAYIDX8]], i32** [[F]], align 8, !dbg [[DBG79]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META81:![0-9]+]], metadata !DIExpression()), !dbg [[DBG82:![0-9]+]] -// CHECK1-NEXT: store i32* [[A_ADDR]], i32** [[G]], align 8, !dbg [[DBG82]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META83:![0-9]+]], metadata !DIExpression()), !dbg [[DBG84:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B4]], i64 0, i64 1, !dbg [[DBG85:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG85]] -// CHECK1-NEXT: store i32* [[ARRAYIDX10]], i32** [[H]], align 8, !dbg [[DBG84]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META86:![0-9]+]], metadata !DIExpression()), !dbg [[DBG87:![0-9]+]] -// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG87]] -// CHECK1-NEXT: store i32 5, i32* [[A_ADDR]], align 4, !dbg [[DBG88:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B4]], i64 0, i64 0, !dbg [[DBG89:![0-9]+]] -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG90:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG89]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG89]] -// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX12]], align 4, !dbg [[DBG91:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG92:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG92]] -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG93:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP21]] to i64, !dbg [[DBG92]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG92]] -// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX16]], align 4, !dbg [[DBG94:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG95:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG95]] -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG96:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG95]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG95]] -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[ARRAYIDX20]], align 4, !dbg [[DBG95]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B4]], i64 0, i64 0, !dbg [[DBG97:![0-9]+]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG98:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP24]] to i64, !dbg [[DBG97]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG97]] -// CHECK1-NEXT: store i32 [[TMP23]], i32* [[ARRAYIDX23]], align 4, !dbg [[DBG99:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B4]], i64 0, i64 0, !dbg [[DBG100:![0-9]+]] -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG101:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP25]] to i64, !dbg [[DBG100]] -// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG100]] -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[ARRAYIDX26]], align 4, !dbg [[DBG100]] -// CHECK1-NEXT: [[TMP27:%.*]] = load i8, i8* [[TMP7]], align 1, !dbg [[DBG102:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP27]] to i1, !dbg [[DBG102]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG102]] -// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP26]], !dbg [[DBG102]] -// CHECK1-NEXT: [[TOBOOL27:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG102]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL27]] to i8, !dbg [[DBG102]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], i8* [[TMP7]], align 1, !dbg [[DBG102]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG103:![0-9]+]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP22]], 1, !dbg [[DBG81:![0-9]+]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG81]] +// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4, !dbg [[DBG81]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META82:![0-9]+]], metadata !DIExpression()), !dbg [[DBG85:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 1, !dbg [[DBG86:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG86]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG86]] +// CHECK1-NEXT: store i32* [[ARRAYIDX8]], i32** [[F]], align 8, !dbg [[DBG85]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META87:![0-9]+]], metadata !DIExpression()), !dbg [[DBG88:![0-9]+]] +// CHECK1-NEXT: store i32* [[A_ADDR]], i32** [[G]], align 8, !dbg [[DBG88]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META89:![0-9]+]], metadata !DIExpression()), !dbg [[DBG90:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B4]], i64 0, i64 1, !dbg [[DBG91:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG91]] +// CHECK1-NEXT: store i32* [[ARRAYIDX10]], i32** [[H]], align 8, !dbg [[DBG90]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META92:![0-9]+]], metadata !DIExpression()), !dbg [[DBG93:![0-9]+]] +// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG93]] +// CHECK1-NEXT: store i32 5, i32* [[A_ADDR]], align 4, !dbg [[DBG94:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B4]], i64 0, i64 0, !dbg [[DBG95:![0-9]+]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG96:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG95]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG95]] +// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX12]], align 4, !dbg [[DBG97:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG98:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG98]] +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG99:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP24]] to i64, !dbg [[DBG98]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG98]] +// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX16]], align 4, !dbg [[DBG100:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG101:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG101]] +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG102:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP25]] to i64, !dbg [[DBG101]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG101]] +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[ARRAYIDX20]], align 4, !dbg [[DBG101]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B4]], i64 0, i64 0, !dbg [[DBG103:![0-9]+]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG104:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP27]] to i64, !dbg [[DBG103]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG103]] +// CHECK1-NEXT: store i32 [[TMP26]], i32* [[ARRAYIDX23]], align 4, !dbg [[DBG105:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[B4]], i64 0, i64 0, !dbg [[DBG106:![0-9]+]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG107:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP28]] to i64, !dbg [[DBG106]] +// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG106]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[ARRAYIDX26]], align 4, !dbg [[DBG106]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i8, i8* [[TMP10]], align 1, !dbg [[DBG108:![0-9]+]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP30]] to i1, !dbg [[DBG108]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG108]] +// CHECK1-NEXT: [[OR:%.*]] = or i32 [[CONV]], [[TMP29]], !dbg [[DBG108]] +// CHECK1-NEXT: [[TOBOOL27:%.*]] = icmp ne i32 [[OR]], 0, !dbg [[DBG108]] +// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL27]] to i8, !dbg [[DBG108]] +// CHECK1-NEXT: store i8 [[FROMBOOL]], i8* [[TMP10]], align 1, !dbg [[DBG108]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG109:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG74]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG80]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP28]], 1, !dbg [[DBG65]] -// CHECK1-NEXT: store i32 [[ADD28]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG65]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG74]], !llvm.loop [[LOOP104:![0-9]+]] +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP31]], 1, !dbg [[DBG71]] +// CHECK1-NEXT: store i32 [[ADD28]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG71]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG80]], !llvm.loop [[LOOP110:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG74]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG80]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP29]], [[TMP30]], !dbg [[DBG65]] -// CHECK1-NEXT: store i32 [[ADD29]], i32* [[DOTOMP_LB]], align 4, !dbg [[DBG65]] -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG68]] -// CHECK1-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP31]], [[TMP32]], !dbg [[DBG65]] -// CHECK1-NEXT: store i32 [[ADD30]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG65]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG74]], !llvm.loop [[LOOP106:![0-9]+]] +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP32]], [[TMP33]], !dbg [[DBG71]] +// CHECK1-NEXT: store i32 [[ADD29]], i32* [[DOTOMP_LB]], align 4, !dbg [[DBG71]] +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG74]] +// CHECK1-NEXT: [[ADD30:%.*]] = add nsw i32 [[TMP34]], [[TMP35]], !dbg [[DBG71]] +// CHECK1-NEXT: store i32 [[ADD30]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG71]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG80]], !llvm.loop [[LOOP112:![0-9]+]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB5:[0-9]+]], i32 [[TMP11]]), !dbg [[DBG105:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG107:![0-9]+]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB5:[0-9]+]], i32 [[TMP14]]), !dbg [[DBG111:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG113:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__ -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG108:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG114:![0-9]+]] !noalias !121 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -298,35 +304,37 @@ // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META115:![0-9]+]], metadata !DIExpression()), !dbg [[DBG116:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META124:![0-9]+]], metadata !DIExpression()), !dbg [[DBG125:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META117:![0-9]+]], metadata !DIExpression()), !dbg [[DBG116]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META126:![0-9]+]], metadata !DIExpression()), !dbg [[DBG125]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META118:![0-9]+]], metadata !DIExpression()), !dbg [[DBG116]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META127:![0-9]+]], metadata !DIExpression()), !dbg [[DBG125]] // CHECK1-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META119:![0-9]+]], metadata !DIExpression()), !dbg [[DBG116]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META128:![0-9]+]], metadata !DIExpression()), !dbg [[DBG125]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META120:![0-9]+]], metadata !DIExpression()), !dbg [[DBG116]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META129:![0-9]+]], metadata !DIExpression()), !dbg [[DBG125]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META121:![0-9]+]], metadata !DIExpression()), !dbg [[DBG116]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG122:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP5]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG122]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8* [[TMP8]] to i8 addrspace(1)*, !dbg [[DBG122]] -// CHECK1-NEXT: call void @__omp_outlined___debug__(i32* [[TMP3]], i32* [[TMP4]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP9]], i32 [[TMP6]], [10 x [10 x i32]]* [[TMP7]], i8 addrspace(1)* [[TMP10]]) #[[ATTR3:[0-9]+]], !dbg [[DBG122]] -// CHECK1-NEXT: ret void, !dbg [[DBG122]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META130:![0-9]+]], metadata !DIExpression()), !dbg [[DBG125]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG131:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP4:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP3]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META121:![0-9]+]]), !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META121]]), !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP9:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP7]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG131]] +// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast i8* [[TMP10]] to i8 addrspace(1)*, !dbg [[DBG131]] +// CHECK1-NEXT: call void @__omp_outlined___debug__(i32* [[TMP4]], i32* [[TMP6]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP11]], i32 [[TMP8]], [10 x [10 x i32]]* [[TMP9]], i8 addrspace(1)* [[TMP12]]) #[[ATTR4:[0-9]+]], !dbg [[DBG131]] +// CHECK1-NEXT: ret void, !dbg [[DBG131]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13 -// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]], i64 [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR4:[0-9]+]] !dbg [[DBG106:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]], i64 [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR6:[0-9]+]] !dbg [[DBG132:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]]*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 @@ -334,34 +342,34 @@ // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META126:![0-9]+]], metadata !DIExpression()), !dbg [[DBG127:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META135:![0-9]+]], metadata !DIExpression()), !dbg [[DBG136:![0-9]+]] // CHECK1-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META128:![0-9]+]], metadata !DIExpression()), !dbg [[DBG127]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META137:![0-9]+]], metadata !DIExpression()), !dbg [[DBG136]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META129:![0-9]+]], metadata !DIExpression()), !dbg [[DBG127]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META138:![0-9]+]], metadata !DIExpression()), !dbg [[DBG136]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META130:![0-9]+]], metadata !DIExpression()), !dbg [[DBG127]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META139:![0-9]+]], metadata !DIExpression()), !dbg [[DBG136]] // CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], i64* [[DOTCAPTURE_EXPR__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[DOTCAPTURE_EXPR__ADDR]], metadata [[META131:![0-9]+]], metadata !DIExpression()), !dbg [[DBG127]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG132:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG132]] -// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG132]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG132]] -// CHECK1-NEXT: [[CONV1:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__ADDR]] to i8*, !dbg [[DBG132]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG132]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG132]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG132]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG132]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i8, i8* [[CONV1]], align 8, !dbg [[DBG132]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP7]] to i1, !dbg [[DBG132]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP3]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG132]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8* [[TMP6]] to i8 addrspace(1)*, !dbg [[DBG132]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP8]], i32 [[TMP4]], [10 x [10 x i32]]* [[TMP5]], i8 addrspace(1)* [[TMP9]], i1 [[TOBOOL]]) #[[ATTR3]], !dbg [[DBG132]] -// CHECK1-NEXT: ret void, !dbg [[DBG132]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[DOTCAPTURE_EXPR__ADDR]], metadata [[META140:![0-9]+]], metadata !DIExpression()), !dbg [[DBG136]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG141:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG141]] +// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG141]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG141]] +// CHECK1-NEXT: [[CONV1:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__ADDR]] to i8*, !dbg [[DBG141]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG141]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG141]] +// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG141]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG141]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i8, i8* [[CONV1]], align 8, !dbg [[DBG141]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP7]] to i1, !dbg [[DBG141]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP3]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG141]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8* [[TMP6]] to i8 addrspace(1)*, !dbg [[DBG141]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l13_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP8]], i32 [[TMP4]], [10 x [10 x i32]]* [[TMP5]], i8 addrspace(1)* [[TMP9]], i1 [[TOBOOL]]) #[[ATTR4]], !dbg [[DBG141]] +// CHECK1-NEXT: ret void, !dbg [[DBG141]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug__ -// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG133:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG142:![0-9]+]] !noalias !147 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]] addrspace(1)*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 @@ -373,55 +381,58 @@ // CHECK1-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [4 x i8*], align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META138:![0-9]+]], metadata !DIExpression()), !dbg [[DBG139:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META150:![0-9]+]], metadata !DIExpression()), !dbg [[DBG151:![0-9]+]] // CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META140:![0-9]+]], metadata !DIExpression()), !dbg [[DBG141:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META152:![0-9]+]], metadata !DIExpression()), !dbg [[DBG153:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]] addrspace(1)* [[B]], [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META142:![0-9]+]], metadata !DIExpression()), !dbg [[DBG143:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META154:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META144:![0-9]+]], metadata !DIExpression()), !dbg [[DBG145:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG146:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG146]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG146]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG146]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG146]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP3]] to [10 x [10 x i32]]*, !dbg [[DBG146]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP4]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG146]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG146]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG146]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast i8 addrspace(1)* [[TMP6]] to i8*, !dbg [[DBG146]] -// CHECK1-NEXT: store i8* [[TMP7]], i8** [[_TMP2]], align 8, !dbg [[DBG146]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG146]] -// CHECK1-NEXT: [[TMP9:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB10:[0-9]+]], i8 2, i1 false, i1 false), !dbg [[DBG146]] -// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP9]], -1, !dbg [[DBG146]] -// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG146]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META156:![0-9]+]], metadata !DIExpression()), !dbg [[DBG157:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG158:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META147:![0-9]+]]), !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG158]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP5:%.*]] = call [10 x [10 x i32]] addrspace(1)* @llvm.noalias.p1a10a10i32.p0i8.p0p1a10a10i32.i64([10 x [10 x i32]] addrspace(1)* [[TMP4]], i8* null, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], i64 0, metadata [[META147]]), !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP5]] to [10 x [10 x i32]]*, !dbg [[DBG158]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP6]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP9:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP8]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META147]]), !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8 addrspace(1)* [[TMP9]] to i8*, !dbg [[DBG158]] +// CHECK1-NEXT: store i8* [[TMP10]], i8** [[_TMP2]], align 8, !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG158]] +// CHECK1-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB10:[0-9]+]], i8 2, i1 false, i1 false), !dbg [[DBG158]] +// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP12]], -1, !dbg [[DBG158]] +// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG158]] // CHECK1: user_code.entry: -// CHECK1-NEXT: [[TMP10:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB15:[0-9]+]]) -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG147:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG147]] -// CHECK1-NEXT: store i32 [[TMP11]], i32* [[CONV]], align 4, !dbg [[DBG147]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG147]] -// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG147]] -// CHECK1-NEXT: [[TMP14:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP2]] to i8*, !dbg [[DBG147]] -// CHECK1-NEXT: store i8* [[TMP14]], i8** [[TMP13]], align 8, !dbg [[DBG147]] -// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG147]] -// CHECK1-NEXT: [[TMP16:%.*]] = inttoptr i64 [[TMP12]] to i8*, !dbg [[DBG147]] -// CHECK1-NEXT: store i8* [[TMP16]], i8** [[TMP15]], align 8, !dbg [[DBG147]] -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG147]] -// CHECK1-NEXT: [[TMP18:%.*]] = bitcast [10 x [10 x i32]]* [[TMP5]] to i8*, !dbg [[DBG147]] -// CHECK1-NEXT: store i8* [[TMP18]], i8** [[TMP17]], align 8, !dbg [[DBG147]] -// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG147]] -// CHECK1-NEXT: store i8* [[TMP8]], i8** [[TMP19]], align 8, !dbg [[DBG147]] -// CHECK1-NEXT: [[TMP20:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG147]] -// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB15]], i32 [[TMP10]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i64, [10 x [10 x i32]]*, i8*)* @__omp_outlined__2 to i8*), i8* null, i8** [[TMP20]], i64 4), !dbg [[DBG147]] -// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB17:[0-9]+]], i8 2, i1 false), !dbg [[DBG148:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG150:![0-9]+]] +// CHECK1-NEXT: [[TMP13:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB15:[0-9]+]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG159:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*, !dbg [[DBG159]] +// CHECK1-NEXT: store i32 [[TMP14]], i32* [[CONV]], align 4, !dbg [[DBG159]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i64, i64* [[A_CASTED]], align 8, !dbg [[DBG159]] +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG159]] +// CHECK1-NEXT: [[TMP17:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP3]] to i8*, !dbg [[DBG159]] +// CHECK1-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8, !dbg [[DBG159]] +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG159]] +// CHECK1-NEXT: [[TMP19:%.*]] = inttoptr i64 [[TMP15]] to i8*, !dbg [[DBG159]] +// CHECK1-NEXT: store i8* [[TMP19]], i8** [[TMP18]], align 8, !dbg [[DBG159]] +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG159]] +// CHECK1-NEXT: [[TMP21:%.*]] = bitcast [10 x [10 x i32]]* [[TMP7]] to i8*, !dbg [[DBG159]] +// CHECK1-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !dbg [[DBG159]] +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG159]] +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[TMP22]], align 8, !dbg [[DBG159]] +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG159]] +// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB15]], i32 [[TMP13]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i64, [10 x [10 x i32]]*, i8*)* @__omp_outlined__2 to i8*), i8* null, i8** [[TMP23]], i64 4), !dbg [[DBG159]] +// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB17:[0-9]+]], i8 2, i1 false), !dbg [[DBG160:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG162:![0-9]+]] // CHECK1: worker.exit: -// CHECK1-NEXT: ret void, !dbg [[DBG146]] +// CHECK1-NEXT: ret void, !dbg [[DBG158]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined___debug__1 -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG151:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG163:![0-9]+]] !noalias !166 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -444,140 +455,143 @@ // CHECK1-NEXT: [[H:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META154:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META169:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META156:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META171:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META157:![0-9]+]], metadata !DIExpression()), !dbg [[DBG158:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META172:![0-9]+]], metadata !DIExpression()), !dbg [[DBG173:![0-9]+]] // CHECK1-NEXT: store i32 [[A]], i32* [[A_ADDR]], align 4 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META159:![0-9]+]], metadata !DIExpression()), !dbg [[DBG160:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[A_ADDR]], metadata [[META174:![0-9]+]], metadata !DIExpression()), !dbg [[DBG175:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]] addrspace(1)* [[B]], [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META161:![0-9]+]], metadata !DIExpression()), !dbg [[DBG162:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META176:![0-9]+]], metadata !DIExpression()), !dbg [[DBG177:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META163:![0-9]+]], metadata !DIExpression()), !dbg [[DBG164:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG165:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG165]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG165]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG165]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG165]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP3]] to [10 x [10 x i32]]*, !dbg [[DBG165]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP4]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG165]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG165]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG165]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast i8 addrspace(1)* [[TMP6]] to i8*, !dbg [[DBG165]] -// CHECK1-NEXT: store i8* [[TMP7]], i8** [[_TMP2]], align 8, !dbg [[DBG165]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG165]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IV]], metadata [[META166:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_LB]], metadata [[META167:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155]] -// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG168:![0-9]+]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_UB]], metadata [[META169:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155]] -// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_STRIDE]], metadata [[META170:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155]] -// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IS_LAST]], metadata [[META171:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155]] -// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META172:![0-9]+]], metadata !DIExpression()), !dbg [[DBG155]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG165]] -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4, !dbg [[DBG165]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB12:[0-9]+]], i32 [[TMP10]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG173:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG165]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META178:![0-9]+]], metadata !DIExpression()), !dbg [[DBG179:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG180:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META166:![0-9]+]]), !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG180]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP5:%.*]] = call [10 x [10 x i32]] addrspace(1)* @llvm.noalias.p1a10a10i32.p0i8.p0p1a10a10i32.i64([10 x [10 x i32]] addrspace(1)* [[TMP4]], i8* null, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], i64 0, metadata [[META166]]), !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP5]] to [10 x [10 x i32]]*, !dbg [[DBG180]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP6]], [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP1]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP9:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP8]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META166]]), !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8 addrspace(1)* [[TMP9]] to i8*, !dbg [[DBG180]] +// CHECK1-NEXT: store i8* [[TMP10]], i8** [[_TMP2]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[_TMP2]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IV]], metadata [[META181:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_LB]], metadata [[META182:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170]] +// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG183:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_UB]], metadata [[META184:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170]] +// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_STRIDE]], metadata [[META185:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170]] +// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IS_LAST]], metadata [[META186:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170]] +// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META187:![0-9]+]], metadata !DIExpression()), !dbg [[DBG170]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4, !dbg [[DBG180]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB12:[0-9]+]], i32 [[TMP13]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG188:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG180]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP11]], 9, !dbg [[DBG168]] -// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG168]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP14]], 9, !dbg [[DBG183]] +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG183]] // CHECK1: cond.true: -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG168]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG183]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG168]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG183]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP12]], [[COND_FALSE]] ], !dbg [[DBG168]] -// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: store i32 [[TMP13]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP14]], [[TMP15]], !dbg [[DBG165]] -// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG165]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP15]], [[COND_FALSE]] ], !dbg [[DBG183]] +// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: store i32 [[TMP16]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]], !dbg [[DBG180]] +// CHECK1-NEXT: br i1 [[CMP4]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG180]] // CHECK1: omp.dispatch.body: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG165]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG180]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]], !dbg [[DBG165]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG165]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP19]], [[TMP20]], !dbg [[DBG180]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG180]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1, !dbg [[DBG174:![0-9]+]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG174]] -// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4, !dbg [[DBG174]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META175:![0-9]+]], metadata !DIExpression()), !dbg [[DBG177:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 1, !dbg [[DBG178:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG178]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG178]] -// CHECK1-NEXT: store i32* [[ARRAYIDX7]], i32** [[F]], align 8, !dbg [[DBG177]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META179:![0-9]+]], metadata !DIExpression()), !dbg [[DBG180:![0-9]+]] -// CHECK1-NEXT: store i32* [[A_ADDR]], i32** [[G]], align 8, !dbg [[DBG180]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META181:![0-9]+]], metadata !DIExpression()), !dbg [[DBG182:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP5]], i64 0, i64 1, !dbg [[DBG183:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX8]], i64 0, i64 1, !dbg [[DBG183]] -// CHECK1-NEXT: store i32* [[ARRAYIDX9]], i32** [[H]], align 8, !dbg [[DBG182]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META184:![0-9]+]], metadata !DIExpression()), !dbg [[DBG185:![0-9]+]] -// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG185]] -// CHECK1-NEXT: store i32 5, i32* [[A_ADDR]], align 4, !dbg [[DBG186:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP5]], i64 0, i64 0, !dbg [[DBG187:![0-9]+]] -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG188:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP19]] to i64, !dbg [[DBG187]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX10]], i64 0, i64 [[IDXPROM]], !dbg [[DBG187]] -// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX11]], align 4, !dbg [[DBG189:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG190:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX12]], i64 0, i64 0, !dbg [[DBG190]] -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG191:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM14:%.*]] = sext i32 [[TMP20]] to i64, !dbg [[DBG190]] -// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX13]], i64 0, i64 [[IDXPROM14]], !dbg [[DBG190]] -// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX15]], align 4, !dbg [[DBG192:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG193:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX16]], i64 0, i64 0, !dbg [[DBG193]] -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG194:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP21]] to i64, !dbg [[DBG193]] -// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG193]] -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[ARRAYIDX19]], align 4, !dbg [[DBG193]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP5]], i64 0, i64 0, !dbg [[DBG195:![0-9]+]] -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG196:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM21:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG195]] -// CHECK1-NEXT: [[ARRAYIDX22:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX20]], i64 0, i64 [[IDXPROM21]], !dbg [[DBG195]] -// CHECK1-NEXT: store i32 [[TMP22]], i32* [[ARRAYIDX22]], align 4, !dbg [[DBG197:![0-9]+]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i8, i8* [[TMP8]], align 1, !dbg [[DBG198:![0-9]+]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP24]] to i1, !dbg [[DBG198]] -// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG198]] -// CHECK1-NEXT: store i32 [[CONV]], i32* [[D]], align 4, !dbg [[DBG199:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG200:![0-9]+]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP21]], 1, !dbg [[DBG189:![0-9]+]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG189]] +// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4, !dbg [[DBG189]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META190:![0-9]+]], metadata !DIExpression()), !dbg [[DBG192:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 1, !dbg [[DBG193:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG193]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX6]], i64 0, i64 1, !dbg [[DBG193]] +// CHECK1-NEXT: store i32* [[ARRAYIDX7]], i32** [[F]], align 8, !dbg [[DBG192]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META194:![0-9]+]], metadata !DIExpression()), !dbg [[DBG195:![0-9]+]] +// CHECK1-NEXT: store i32* [[A_ADDR]], i32** [[G]], align 8, !dbg [[DBG195]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META196:![0-9]+]], metadata !DIExpression()), !dbg [[DBG197:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP7]], i64 0, i64 1, !dbg [[DBG198:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX8]], i64 0, i64 1, !dbg [[DBG198]] +// CHECK1-NEXT: store i32* [[ARRAYIDX9]], i32** [[H]], align 8, !dbg [[DBG197]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META199:![0-9]+]], metadata !DIExpression()), !dbg [[DBG200:![0-9]+]] +// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG200]] +// CHECK1-NEXT: store i32 5, i32* [[A_ADDR]], align 4, !dbg [[DBG201:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP7]], i64 0, i64 0, !dbg [[DBG202:![0-9]+]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG203:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG202]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX10]], i64 0, i64 [[IDXPROM]], !dbg [[DBG202]] +// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX11]], align 4, !dbg [[DBG204:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG205:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX12]], i64 0, i64 0, !dbg [[DBG205]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG206:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM14:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG205]] +// CHECK1-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX13]], i64 0, i64 [[IDXPROM14]], !dbg [[DBG205]] +// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX15]], align 4, !dbg [[DBG207:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG208:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX16]], i64 0, i64 0, !dbg [[DBG208]] +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG209:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM18:%.*]] = sext i32 [[TMP24]] to i64, !dbg [[DBG208]] +// CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX17]], i64 0, i64 [[IDXPROM18]], !dbg [[DBG208]] +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[ARRAYIDX19]], align 4, !dbg [[DBG208]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP7]], i64 0, i64 0, !dbg [[DBG210:![0-9]+]] +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[A_ADDR]], align 4, !dbg [[DBG211:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM21:%.*]] = sext i32 [[TMP26]] to i64, !dbg [[DBG210]] +// CHECK1-NEXT: [[ARRAYIDX22:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX20]], i64 0, i64 [[IDXPROM21]], !dbg [[DBG210]] +// CHECK1-NEXT: store i32 [[TMP25]], i32* [[ARRAYIDX22]], align 4, !dbg [[DBG212:![0-9]+]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i8, i8* [[TMP11]], align 1, !dbg [[DBG213:![0-9]+]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = trunc i8 [[TMP27]] to i1, !dbg [[DBG213]] +// CHECK1-NEXT: [[CONV:%.*]] = zext i1 [[TOBOOL]] to i32, !dbg [[DBG213]] +// CHECK1-NEXT: store i32 [[CONV]], i32* [[D]], align 4, !dbg [[DBG214:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG215:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG173]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG188]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP25]], 1, !dbg [[DBG165]] -// CHECK1-NEXT: store i32 [[ADD23]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG165]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG173]], !llvm.loop [[LOOP201:![0-9]+]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[ADD23:%.*]] = add nsw i32 [[TMP28]], 1, !dbg [[DBG180]] +// CHECK1-NEXT: store i32 [[ADD23]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG180]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG188]], !llvm.loop [[LOOP216:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG173]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG188]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP26]], [[TMP27]], !dbg [[DBG165]] -// CHECK1-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_LB]], align 4, !dbg [[DBG165]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG168]] -// CHECK1-NEXT: [[ADD25:%.*]] = add nsw i32 [[TMP28]], [[TMP29]], !dbg [[DBG165]] -// CHECK1-NEXT: store i32 [[ADD25]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG165]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG173]], !llvm.loop [[LOOP203:![0-9]+]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP29]], [[TMP30]], !dbg [[DBG180]] +// CHECK1-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_LB]], align 4, !dbg [[DBG180]] +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG183]] +// CHECK1-NEXT: [[ADD25:%.*]] = add nsw i32 [[TMP31]], [[TMP32]], !dbg [[DBG180]] +// CHECK1-NEXT: store i32 [[ADD25]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG180]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG188]], !llvm.loop [[LOOP218:![0-9]+]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB14:[0-9]+]], i32 [[TMP10]]), !dbg [[DBG202:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG204:![0-9]+]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB14:[0-9]+]], i32 [[TMP13]]), !dbg [[DBG217:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG219:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__2 -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG205:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG220:![0-9]+]] !noalias !221 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -586,66 +600,68 @@ // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META206:![0-9]+]], metadata !DIExpression()), !dbg [[DBG207:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META224:![0-9]+]], metadata !DIExpression()), !dbg [[DBG225:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META208:![0-9]+]], metadata !DIExpression()), !dbg [[DBG207]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META226:![0-9]+]], metadata !DIExpression()), !dbg [[DBG225]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META209:![0-9]+]], metadata !DIExpression()), !dbg [[DBG207]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META227:![0-9]+]], metadata !DIExpression()), !dbg [[DBG225]] // CHECK1-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META210:![0-9]+]], metadata !DIExpression()), !dbg [[DBG207]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META228:![0-9]+]], metadata !DIExpression()), !dbg [[DBG225]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META211:![0-9]+]], metadata !DIExpression()), !dbg [[DBG207]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META229:![0-9]+]], metadata !DIExpression()), !dbg [[DBG225]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META212:![0-9]+]], metadata !DIExpression()), !dbg [[DBG207]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG213:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP8:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP5]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP7]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG213]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast i8* [[TMP8]] to i8 addrspace(1)*, !dbg [[DBG213]] -// CHECK1-NEXT: call void @__omp_outlined___debug__1(i32* [[TMP3]], i32* [[TMP4]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP9]], i32 [[TMP6]], [10 x [10 x i32]] addrspace(1)* [[TMP10]], i8 addrspace(1)* [[TMP11]]) #[[ATTR3]], !dbg [[DBG213]] -// CHECK1-NEXT: ret void, !dbg [[DBG213]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META230:![0-9]+]], metadata !DIExpression()), !dbg [[DBG225]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG231:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP4:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP3]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META221:![0-9]+]]), !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META221]]), !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP7:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP9:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP10:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP7]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP9]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG231]] +// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast i8* [[TMP10]] to i8 addrspace(1)*, !dbg [[DBG231]] +// CHECK1-NEXT: call void @__omp_outlined___debug__1(i32* [[TMP4]], i32* [[TMP6]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP11]], i32 [[TMP8]], [10 x [10 x i32]] addrspace(1)* [[TMP12]], i8 addrspace(1)* [[TMP13]]) #[[ATTR4]], !dbg [[DBG231]] +// CHECK1-NEXT: ret void, !dbg [[DBG231]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27 -// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR4]] !dbg [[DBG190:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i64 [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR6]] !dbg [[DBG232:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]]*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8 // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META217:![0-9]+]], metadata !DIExpression()), !dbg [[DBG218:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META235:![0-9]+]], metadata !DIExpression()), !dbg [[DBG236:![0-9]+]] // CHECK1-NEXT: store i64 [[A]], i64* [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META219:![0-9]+]], metadata !DIExpression()), !dbg [[DBG218]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i64* [[A_ADDR]], metadata [[META237:![0-9]+]], metadata !DIExpression()), !dbg [[DBG236]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META220:![0-9]+]], metadata !DIExpression()), !dbg [[DBG218]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META238:![0-9]+]], metadata !DIExpression()), !dbg [[DBG236]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META221:![0-9]+]], metadata !DIExpression()), !dbg [[DBG218]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG222:![0-9]+]] -// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG222]] -// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG222]] -// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG222]] -// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG222]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG222]] -// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG222]] -// CHECK1-NEXT: [[TMP6:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG222]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP3]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG222]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP5]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG222]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8* [[TMP6]] to i8 addrspace(1)*, !dbg [[DBG222]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP7]], i32 [[TMP4]], [10 x [10 x i32]] addrspace(1)* [[TMP8]], i8 addrspace(1)* [[TMP9]]) #[[ATTR3]], !dbg [[DBG222]] -// CHECK1-NEXT: ret void, !dbg [[DBG222]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META239:![0-9]+]], metadata !DIExpression()), !dbg [[DBG236]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG240:![0-9]+]] +// CHECK1-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*, !dbg [[DBG240]] +// CHECK1-NEXT: [[TMP1:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG240]] +// CHECK1-NEXT: [[TMP2:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG240]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG240]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, i32* [[CONV]], align 8, !dbg [[DBG240]] +// CHECK1-NEXT: [[TMP5:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG240]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG240]] +// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP3]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG240]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP5]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG240]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i8* [[TMP6]] to i8 addrspace(1)*, !dbg [[DBG240]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l27_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP7]], i32 [[TMP4]], [10 x [10 x i32]] addrspace(1)* [[TMP8]], i8 addrspace(1)* [[TMP9]]) #[[ATTR4]], !dbg [[DBG240]] +// CHECK1-NEXT: ret void, !dbg [[DBG240]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug__ -// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 addrspace(1)* noalias [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG223:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 addrspace(1)* noalias [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG241:![0-9]+]] !noalias !246 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]] addrspace(1)*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32 addrspace(1)*, align 8 @@ -657,55 +673,59 @@ // CHECK1-NEXT: [[_TMP3:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [4 x i8*], align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META228:![0-9]+]], metadata !DIExpression()), !dbg [[DBG229:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META249:![0-9]+]], metadata !DIExpression()), !dbg [[DBG250:![0-9]+]] // CHECK1-NEXT: store i32 addrspace(1)* [[A]], i32 addrspace(1)** [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32 addrspace(1)** [[A_ADDR]], metadata [[META230:![0-9]+]], metadata !DIExpression()), !dbg [[DBG231:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32 addrspace(1)** [[A_ADDR]], metadata [[META251:![0-9]+]], metadata !DIExpression()), !dbg [[DBG252:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]] addrspace(1)* [[B]], [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META232:![0-9]+]], metadata !DIExpression()), !dbg [[DBG233:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META253:![0-9]+]], metadata !DIExpression()), !dbg [[DBG254:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META234:![0-9]+]], metadata !DIExpression()), !dbg [[DBG235:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG236:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG236]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32 addrspace(1)*, i32 addrspace(1)** [[A_ADDR]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast i32 addrspace(1)* [[TMP3]] to i32*, !dbg [[DBG236]] -// CHECK1-NEXT: store i32* [[TMP4]], i32** [[_TMP1]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[_TMP1]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP6]] to [10 x [10 x i32]]*, !dbg [[DBG236]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP7]], [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8 addrspace(1)* [[TMP9]] to i8*, !dbg [[DBG236]] -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[_TMP3]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[_TMP3]], align 8, !dbg [[DBG236]] -// CHECK1-NEXT: [[TMP12:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB19:[0-9]+]], i8 2, i1 false, i1 false), !dbg [[DBG236]] -// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP12]], -1, !dbg [[DBG236]] -// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG236]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META255:![0-9]+]], metadata !DIExpression()), !dbg [[DBG256:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG257:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META246:![0-9]+]]), !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG257]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32 addrspace(1)*, i32 addrspace(1)** [[A_ADDR]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP5:%.*]] = call i32 addrspace(1)* @llvm.noalias.p1i32.p0i8.p0p1i32.i64(i32 addrspace(1)* [[TMP4]], i8* null, i32 addrspace(1)** [[A_ADDR]], i64 0, metadata [[META246]]), !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast i32 addrspace(1)* [[TMP5]] to i32*, !dbg [[DBG257]] +// CHECK1-NEXT: store i32* [[TMP6]], i32** [[_TMP1]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32*, i32** [[_TMP1]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP9:%.*]] = call [10 x [10 x i32]] addrspace(1)* @llvm.noalias.p1a10a10i32.p0i8.p0p1a10a10i32.i64([10 x [10 x i32]] addrspace(1)* [[TMP8]], i8* null, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], i64 0, metadata [[META246]]), !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP9]] to [10 x [10 x i32]]*, !dbg [[DBG257]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP10]], [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP11:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP13:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP12]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META246]]), !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP14:%.*]] = addrspacecast i8 addrspace(1)* [[TMP13]] to i8*, !dbg [[DBG257]] +// CHECK1-NEXT: store i8* [[TMP14]], i8** [[_TMP3]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i8*, i8** [[_TMP3]], align 8, !dbg [[DBG257]] +// CHECK1-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB19:[0-9]+]], i8 2, i1 false, i1 false), !dbg [[DBG257]] +// CHECK1-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP16]], -1, !dbg [[DBG257]] +// CHECK1-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]], !dbg [[DBG257]] // CHECK1: user_code.entry: -// CHECK1-NEXT: [[TMP13:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB24:[0-9]+]]) -// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG237:![0-9]+]] -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP2]] to i8*, !dbg [[DBG237]] -// CHECK1-NEXT: store i8* [[TMP15]], i8** [[TMP14]], align 8, !dbg [[DBG237]] -// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG237]] -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP5]] to i8*, !dbg [[DBG237]] -// CHECK1-NEXT: store i8* [[TMP17]], i8** [[TMP16]], align 8, !dbg [[DBG237]] -// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG237]] -// CHECK1-NEXT: [[TMP19:%.*]] = bitcast [10 x [10 x i32]]* [[TMP8]] to i8*, !dbg [[DBG237]] -// CHECK1-NEXT: store i8* [[TMP19]], i8** [[TMP18]], align 8, !dbg [[DBG237]] -// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG237]] -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[TMP20]], align 8, !dbg [[DBG237]] -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG237]] -// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB24]], i32 [[TMP13]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i32*, [10 x [10 x i32]]*, i8*)* @__omp_outlined__4 to i8*), i8* null, i8** [[TMP21]], i64 4), !dbg [[DBG237]] -// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB26:[0-9]+]], i8 2, i1 false), !dbg [[DBG238:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG240:![0-9]+]] +// CHECK1-NEXT: [[TMP17:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB24:[0-9]+]]) +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 0, !dbg [[DBG258:![0-9]+]] +// CHECK1-NEXT: [[TMP19:%.*]] = bitcast [10 x [10 x [10 x i32]]]* [[TMP3]] to i8*, !dbg [[DBG258]] +// CHECK1-NEXT: store i8* [[TMP19]], i8** [[TMP18]], align 8, !dbg [[DBG258]] +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 1, !dbg [[DBG258]] +// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP7]] to i8*, !dbg [[DBG258]] +// CHECK1-NEXT: store i8* [[TMP21]], i8** [[TMP20]], align 8, !dbg [[DBG258]] +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 2, !dbg [[DBG258]] +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast [10 x [10 x i32]]* [[TMP11]] to i8*, !dbg [[DBG258]] +// CHECK1-NEXT: store i8* [[TMP23]], i8** [[TMP22]], align 8, !dbg [[DBG258]] +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [4 x i8*], [4 x i8*]* [[CAPTURED_VARS_ADDRS]], i64 0, i64 3, !dbg [[DBG258]] +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[TMP24]], align 8, !dbg [[DBG258]] +// CHECK1-NEXT: [[TMP25:%.*]] = bitcast [4 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**, !dbg [[DBG258]] +// CHECK1-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* @[[GLOB24]], i32 [[TMP17]], i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*, [10 x [10 x [10 x i32]]]*, i32*, [10 x [10 x i32]]*, i8*)* @__omp_outlined__4 to i8*), i8* null, i8** [[TMP25]], i64 4), !dbg [[DBG258]] +// CHECK1-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB26:[0-9]+]], i8 2, i1 false), !dbg [[DBG259:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG261:![0-9]+]] // CHECK1: worker.exit: -// CHECK1-NEXT: ret void, !dbg [[DBG236]] +// CHECK1-NEXT: ret void, !dbg [[DBG257]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined___debug__3 -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 addrspace(1)* noalias [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG241:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]] addrspace(1)* noalias [[C:%.*]], i32 addrspace(1)* noalias [[A:%.*]], [10 x [10 x i32]] addrspace(1)* noalias [[B:%.*]], i8 addrspace(1)* noalias [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG262:![0-9]+]] !noalias !265 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -729,148 +749,152 @@ // CHECK1-NEXT: [[H:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[D:%.*]] = alloca i32, align 4 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META244:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META268:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META246:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META270:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]] addrspace(1)* [[C]], [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META247:![0-9]+]], metadata !DIExpression()), !dbg [[DBG248:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], metadata [[META271:![0-9]+]], metadata !DIExpression()), !dbg [[DBG272:![0-9]+]] // CHECK1-NEXT: store i32 addrspace(1)* [[A]], i32 addrspace(1)** [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32 addrspace(1)** [[A_ADDR]], metadata [[META249:![0-9]+]], metadata !DIExpression()), !dbg [[DBG250:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32 addrspace(1)** [[A_ADDR]], metadata [[META273:![0-9]+]], metadata !DIExpression()), !dbg [[DBG274:![0-9]+]] // CHECK1-NEXT: store [10 x [10 x i32]] addrspace(1)* [[B]], [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META251:![0-9]+]], metadata !DIExpression()), !dbg [[DBG252:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], metadata [[META275:![0-9]+]], metadata !DIExpression()), !dbg [[DBG276:![0-9]+]] // CHECK1-NEXT: store i8 addrspace(1)* [[BB]], i8 addrspace(1)** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META253:![0-9]+]], metadata !DIExpression()), !dbg [[DBG254:![0-9]+]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG255:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG255]] -// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP1]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i32 addrspace(1)*, i32 addrspace(1)** [[A_ADDR]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP4:%.*]] = addrspacecast i32 addrspace(1)* [[TMP3]] to i32*, !dbg [[DBG255]] -// CHECK1-NEXT: store i32* [[TMP4]], i32** [[_TMP1]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[_TMP1]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP7:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP6]] to [10 x [10 x i32]]*, !dbg [[DBG255]] -// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP7]], [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast i8 addrspace(1)* [[TMP9]] to i8*, !dbg [[DBG255]] -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[_TMP3]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[_TMP3]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IV]], metadata [[META256:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_LB]], metadata [[META257:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245]] -// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG258:![0-9]+]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_UB]], metadata [[META259:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245]] -// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_STRIDE]], metadata [[META260:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245]] -// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IS_LAST]], metadata [[META261:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245]] -// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META262:![0-9]+]], metadata !DIExpression()), !dbg [[DBG245]] -// CHECK1-NEXT: [[TMP12:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4, !dbg [[DBG255]] -// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB21:[0-9]+]], i32 [[TMP13]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG263:![0-9]+]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG255]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8 addrspace(1)** [[BB_ADDR]], metadata [[META277:![0-9]+]], metadata !DIExpression()), !dbg [[DBG278:![0-9]+]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]] addrspace(1)*, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], align 8, !dbg [[DBG279:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = call [10 x [10 x [10 x i32]]] addrspace(1)* @llvm.noalias.p1a10a10a10i32.p0i8.p0p1a10a10a10i32.i64([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP0]], i8* null, [10 x [10 x [10 x i32]]] addrspace(1)** [[C_ADDR]], i64 0, metadata [[META265:![0-9]+]]), !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP2:%.*]] = addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP1]] to [10 x [10 x [10 x i32]]]*, !dbg [[DBG279]] +// CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[TMP2]], [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP3:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[TMP]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32 addrspace(1)*, i32 addrspace(1)** [[A_ADDR]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP5:%.*]] = call i32 addrspace(1)* @llvm.noalias.p1i32.p0i8.p0p1i32.i64(i32 addrspace(1)* [[TMP4]], i8* null, i32 addrspace(1)** [[A_ADDR]], i64 0, metadata [[META265]]), !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP6:%.*]] = addrspacecast i32 addrspace(1)* [[TMP5]] to i32*, !dbg [[DBG279]] +// CHECK1-NEXT: store i32* [[TMP6]], i32** [[_TMP1]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32*, i32** [[_TMP1]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]] addrspace(1)*, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP9:%.*]] = call [10 x [10 x i32]] addrspace(1)* @llvm.noalias.p1a10a10i32.p0i8.p0p1a10a10i32.i64([10 x [10 x i32]] addrspace(1)* [[TMP8]], i8* null, [10 x [10 x i32]] addrspace(1)** [[B_ADDR]], i64 0, metadata [[META265]]), !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]] addrspace(1)* [[TMP9]] to [10 x [10 x i32]]*, !dbg [[DBG279]] +// CHECK1-NEXT: store [10 x [10 x i32]]* [[TMP10]], [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP11:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[_TMP2]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)** [[BB_ADDR]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP13:%.*]] = call i8 addrspace(1)* @llvm.noalias.p1i8.p0i8.p0p1i8.i64(i8 addrspace(1)* [[TMP12]], i8* null, i8 addrspace(1)** [[BB_ADDR]], i64 0, metadata [[META265]]), !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP14:%.*]] = addrspacecast i8 addrspace(1)* [[TMP13]] to i8*, !dbg [[DBG279]] +// CHECK1-NEXT: store i8* [[TMP14]], i8** [[_TMP3]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP15:%.*]] = load i8*, i8** [[_TMP3]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IV]], metadata [[META280:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_LB]], metadata [[META281:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269]] +// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG282:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_UB]], metadata [[META283:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269]] +// CHECK1-NEXT: store i32 9, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_STRIDE]], metadata [[META284:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269]] +// CHECK1-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[DOTOMP_IS_LAST]], metadata [[META285:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269]] +// CHECK1-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[I]], metadata [[META286:![0-9]+]], metadata !DIExpression()), !dbg [[DBG269]] +// CHECK1-NEXT: [[TMP16:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP16]], align 4, !dbg [[DBG279]] +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @[[GLOB21:[0-9]+]], i32 [[TMP17]], i32 33, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1), !dbg [[DBG287:![0-9]+]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND:%.*]], !dbg [[DBG279]] // CHECK1: omp.dispatch.cond: -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP14]], 9, !dbg [[DBG258]] -// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG258]] +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP18]], 9, !dbg [[DBG282]] +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]], !dbg [[DBG282]] // CHECK1: cond.true: -// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG258]] +// CHECK1-NEXT: br label [[COND_END:%.*]], !dbg [[DBG282]] // CHECK1: cond.false: -// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG258]] +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: br label [[COND_END]], !dbg [[DBG282]] // CHECK1: cond.end: -// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP15]], [[COND_FALSE]] ], !dbg [[DBG258]] -// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: store i32 [[TMP16]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]], !dbg [[DBG255]] -// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG255]] +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 9, [[COND_TRUE]] ], [ [[TMP19]], [[COND_FALSE]] ], !dbg [[DBG282]] +// CHECK1-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: store i32 [[TMP20]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP21]], [[TMP22]], !dbg [[DBG279]] +// CHECK1-NEXT: br i1 [[CMP5]], label [[OMP_DISPATCH_BODY:%.*]], label [[OMP_DISPATCH_END:%.*]], !dbg [[DBG279]] // CHECK1: omp.dispatch.body: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG255]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]], !dbg [[DBG279]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP19]], [[TMP20]], !dbg [[DBG255]] -// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG255]] +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP23]], [[TMP24]], !dbg [[DBG279]] +// CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]], !dbg [[DBG279]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP21]], 1, !dbg [[DBG264:![0-9]+]] -// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG264]] -// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4, !dbg [[DBG264]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META265:![0-9]+]], metadata !DIExpression()), !dbg [[DBG267:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 1, !dbg [[DBG268:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG268]] -// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG268]] -// CHECK1-NEXT: store i32* [[ARRAYIDX8]], i32** [[F]], align 8, !dbg [[DBG267]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META269:![0-9]+]], metadata !DIExpression()), !dbg [[DBG270:![0-9]+]] -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[G]], align 8, !dbg [[DBG270]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META271:![0-9]+]], metadata !DIExpression()), !dbg [[DBG272:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP8]], i64 0, i64 1, !dbg [[DBG273:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG273]] -// CHECK1-NEXT: store i32* [[ARRAYIDX10]], i32** [[H]], align 8, !dbg [[DBG272]] -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META274:![0-9]+]], metadata !DIExpression()), !dbg [[DBG275:![0-9]+]] -// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG275]] -// CHECK1-NEXT: store i32 5, i32* [[TMP5]], align 4, !dbg [[DBG276:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP8]], i64 0, i64 0, !dbg [[DBG277:![0-9]+]] -// CHECK1-NEXT: [[TMP22:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG278:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP22]] to i64, !dbg [[DBG277]] -// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG277]] -// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX12]], align 4, !dbg [[DBG279:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG280:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG280]] -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG281:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP23]] to i64, !dbg [[DBG280]] -// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG280]] -// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX16]], align 4, !dbg [[DBG282:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP2]], i64 0, i64 0, !dbg [[DBG283:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG283]] -// CHECK1-NEXT: [[TMP24:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG284:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP24]] to i64, !dbg [[DBG283]] -// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG283]] -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[ARRAYIDX20]], align 4, !dbg [[DBG283]] -// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP8]], i64 0, i64 0, !dbg [[DBG285:![0-9]+]] -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG286:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP26]] to i64, !dbg [[DBG285]] -// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG285]] -// CHECK1-NEXT: store i32 [[TMP25]], i32* [[ARRAYIDX23]], align 4, !dbg [[DBG287:![0-9]+]] -// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP8]], i64 0, i64 0, !dbg [[DBG288:![0-9]+]] -// CHECK1-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP5]], align 4, !dbg [[DBG289:![0-9]+]] -// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP27]] to i64, !dbg [[DBG288]] -// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG288]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[ARRAYIDX26]], align 4, !dbg [[DBG288]] -// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP28]], 0, !dbg [[DBG288]] -// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG290:![0-9]+]] -// CHECK1-NEXT: store i8 [[FROMBOOL]], i8* [[TMP11]], align 1, !dbg [[DBG290]] -// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG291:![0-9]+]] +// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP25]], 1, !dbg [[DBG288:![0-9]+]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]], !dbg [[DBG288]] +// CHECK1-NEXT: store i32 [[ADD]], i32* [[I]], align 4, !dbg [[DBG288]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[F]], metadata [[META289:![0-9]+]], metadata !DIExpression()), !dbg [[DBG291:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 1, !dbg [[DBG292:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX]], i64 0, i64 1, !dbg [[DBG292]] +// CHECK1-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX7]], i64 0, i64 1, !dbg [[DBG292]] +// CHECK1-NEXT: store i32* [[ARRAYIDX8]], i32** [[F]], align 8, !dbg [[DBG291]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[G]], metadata [[META293:![0-9]+]], metadata !DIExpression()), !dbg [[DBG294:![0-9]+]] +// CHECK1-NEXT: store i32* [[TMP7]], i32** [[G]], align 8, !dbg [[DBG294]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[H]], metadata [[META295:![0-9]+]], metadata !DIExpression()), !dbg [[DBG296:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP11]], i64 0, i64 1, !dbg [[DBG297:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX9]], i64 0, i64 1, !dbg [[DBG297]] +// CHECK1-NEXT: store i32* [[ARRAYIDX10]], i32** [[H]], align 8, !dbg [[DBG296]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32* [[D]], metadata [[META298:![0-9]+]], metadata !DIExpression()), !dbg [[DBG299:![0-9]+]] +// CHECK1-NEXT: store i32 15, i32* [[D]], align 4, !dbg [[DBG299]] +// CHECK1-NEXT: store i32 5, i32* [[TMP7]], align 4, !dbg [[DBG300:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP11]], i64 0, i64 0, !dbg [[DBG301:![0-9]+]] +// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG302:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP26]] to i64, !dbg [[DBG301]] +// CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX11]], i64 0, i64 [[IDXPROM]], !dbg [[DBG301]] +// CHECK1-NEXT: store i32 10, i32* [[ARRAYIDX12]], align 4, !dbg [[DBG303:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG304:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX13]], i64 0, i64 0, !dbg [[DBG304]] +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG305:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM15:%.*]] = sext i32 [[TMP27]] to i64, !dbg [[DBG304]] +// CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX14]], i64 0, i64 [[IDXPROM15]], !dbg [[DBG304]] +// CHECK1-NEXT: store i32 11, i32* [[ARRAYIDX16]], align 4, !dbg [[DBG306:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x [10 x [10 x i32]]], [10 x [10 x [10 x i32]]]* [[TMP3]], i64 0, i64 0, !dbg [[DBG307:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[ARRAYIDX17]], i64 0, i64 0, !dbg [[DBG307]] +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG308:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM19:%.*]] = sext i32 [[TMP28]] to i64, !dbg [[DBG307]] +// CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX18]], i64 0, i64 [[IDXPROM19]], !dbg [[DBG307]] +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[ARRAYIDX20]], align 4, !dbg [[DBG307]] +// CHECK1-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP11]], i64 0, i64 0, !dbg [[DBG309:![0-9]+]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG310:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM22:%.*]] = sext i32 [[TMP30]] to i64, !dbg [[DBG309]] +// CHECK1-NEXT: [[ARRAYIDX23:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX21]], i64 0, i64 [[IDXPROM22]], !dbg [[DBG309]] +// CHECK1-NEXT: store i32 [[TMP29]], i32* [[ARRAYIDX23]], align 4, !dbg [[DBG311:![0-9]+]] +// CHECK1-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [10 x [10 x i32]], [10 x [10 x i32]]* [[TMP11]], i64 0, i64 0, !dbg [[DBG312:![0-9]+]] +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP7]], align 4, !dbg [[DBG313:![0-9]+]] +// CHECK1-NEXT: [[IDXPROM25:%.*]] = sext i32 [[TMP31]] to i64, !dbg [[DBG312]] +// CHECK1-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[ARRAYIDX24]], i64 0, i64 [[IDXPROM25]], !dbg [[DBG312]] +// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[ARRAYIDX26]], align 4, !dbg [[DBG312]] +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP32]], 0, !dbg [[DBG312]] +// CHECK1-NEXT: [[FROMBOOL:%.*]] = zext i1 [[TOBOOL]] to i8, !dbg [[DBG314:![0-9]+]] +// CHECK1-NEXT: store i8 [[FROMBOOL]], i8* [[TMP15]], align 1, !dbg [[DBG314]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]], !dbg [[DBG315:![0-9]+]] // CHECK1: omp.body.continue: -// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG263]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]], !dbg [[DBG287]] // CHECK1: omp.inner.for.inc: -// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP29]], 1, !dbg [[DBG255]] -// CHECK1-NEXT: store i32 [[ADD27]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG255]] -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG263]], !llvm.loop [[LOOP292:![0-9]+]] +// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[ADD27:%.*]] = add nsw i32 [[TMP33]], 1, !dbg [[DBG279]] +// CHECK1-NEXT: store i32 [[ADD27]], i32* [[DOTOMP_IV]], align 4, !dbg [[DBG279]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !dbg [[DBG287]], !llvm.loop [[LOOP316:![0-9]+]] // CHECK1: omp.inner.for.end: -// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG263]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]], !dbg [[DBG287]] // CHECK1: omp.dispatch.inc: -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP30]], [[TMP31]], !dbg [[DBG255]] -// CHECK1-NEXT: store i32 [[ADD28]], i32* [[DOTOMP_LB]], align 4, !dbg [[DBG255]] -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG258]] -// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP32]], [[TMP33]], !dbg [[DBG255]] -// CHECK1-NEXT: store i32 [[ADD29]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG255]] -// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG263]], !llvm.loop [[LOOP294:![0-9]+]] +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[TMP35:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP34]], [[TMP35]], !dbg [[DBG279]] +// CHECK1-NEXT: store i32 [[ADD28]], i32* [[DOTOMP_LB]], align 4, !dbg [[DBG279]] +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[DOTOMP_STRIDE]], align 4, !dbg [[DBG282]] +// CHECK1-NEXT: [[ADD29:%.*]] = add nsw i32 [[TMP36]], [[TMP37]], !dbg [[DBG279]] +// CHECK1-NEXT: store i32 [[ADD29]], i32* [[DOTOMP_UB]], align 4, !dbg [[DBG279]] +// CHECK1-NEXT: br label [[OMP_DISPATCH_COND]], !dbg [[DBG287]], !llvm.loop [[LOOP318:![0-9]+]] // CHECK1: omp.dispatch.end: -// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB23:[0-9]+]], i32 [[TMP13]]), !dbg [[DBG293:![0-9]+]] -// CHECK1-NEXT: ret void, !dbg [[DBG295:![0-9]+]] +// CHECK1-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB23:[0-9]+]], i32 [[TMP17]]), !dbg [[DBG317:![0-9]+]] +// CHECK1-NEXT: ret void, !dbg [[DBG319:![0-9]+]] // // // CHECK1-LABEL: define {{[^@]+}}@__omp_outlined__4 -// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG296:![0-9]+]] { +// CHECK1-SAME: (i32* noalias [[DOTGLOBAL_TID_:%.*]], i32* noalias [[DOTBOUND_TID_:%.*]], [10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR0]] !dbg [[DBG320:![0-9]+]] !noalias !323 { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8 @@ -879,62 +903,64 @@ // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store i32* [[DOTGLOBAL_TID_]], i32** [[DOTGLOBAL_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META299:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTGLOBAL_TID__ADDR]], metadata [[META326:![0-9]+]], metadata !DIExpression()), !dbg [[DBG327:![0-9]+]] // CHECK1-NEXT: store i32* [[DOTBOUND_TID_]], i32** [[DOTBOUND_TID__ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META301:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[DOTBOUND_TID__ADDR]], metadata [[META328:![0-9]+]], metadata !DIExpression()), !dbg [[DBG327]] // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META302:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META329:![0-9]+]], metadata !DIExpression()), !dbg [[DBG327]] // CHECK1-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META303:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META330:![0-9]+]], metadata !DIExpression()), !dbg [[DBG327]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META304:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META331:![0-9]+]], metadata !DIExpression()), !dbg [[DBG327]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META305:![0-9]+]], metadata !DIExpression()), !dbg [[DBG300]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG306:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP9:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP6]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast i32* [[TMP7]] to i32 addrspace(1)*, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP8]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG306]] -// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast i8* [[TMP9]] to i8 addrspace(1)*, !dbg [[DBG306]] -// CHECK1-NEXT: call void @__omp_outlined___debug__3(i32* [[TMP4]], i32* [[TMP5]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP10]], i32 addrspace(1)* [[TMP11]], [10 x [10 x i32]] addrspace(1)* [[TMP12]], i8 addrspace(1)* [[TMP13]]) #[[ATTR3]], !dbg [[DBG306]] -// CHECK1-NEXT: ret void, !dbg [[DBG306]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META332:![0-9]+]], metadata !DIExpression()), !dbg [[DBG327]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG333:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP4:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP5:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP4]], i8* null, i32** [[DOTGLOBAL_TID__ADDR]], i64 0, metadata [[META323:![0-9]+]]), !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32*, i32** [[DOTBOUND_TID__ADDR]], align 8, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP7:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP6]], i8* null, i32** [[DOTBOUND_TID__ADDR]], i64 0, metadata [[META323]]), !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP8:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP10:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP11:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP12:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP8]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP13:%.*]] = addrspacecast i32* [[TMP9]] to i32 addrspace(1)*, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP14:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP10]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG333]] +// CHECK1-NEXT: [[TMP15:%.*]] = addrspacecast i8* [[TMP11]] to i8 addrspace(1)*, !dbg [[DBG333]] +// CHECK1-NEXT: call void @__omp_outlined___debug__3(i32* [[TMP5]], i32* [[TMP7]], [10 x [10 x [10 x i32]]] addrspace(1)* [[TMP12]], i32 addrspace(1)* [[TMP13]], [10 x [10 x i32]] addrspace(1)* [[TMP14]], i8 addrspace(1)* [[TMP15]]) #[[ATTR4]], !dbg [[DBG333]] +// CHECK1-NEXT: ret void, !dbg [[DBG333]] // // // CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41 -// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR4]] !dbg [[DBG269:![0-9]+]] { +// CHECK1-SAME: ([10 x [10 x [10 x i32]]]* nonnull align 4 dereferenceable(4000) [[C:%.*]], i32* nonnull align 4 dereferenceable(4) [[A:%.*]], [10 x [10 x i32]]* nonnull align 4 dereferenceable(400) [[B:%.*]], i8* nonnull align 1 dereferenceable(1) [[BB:%.*]]) #[[ATTR6]] !dbg [[DBG334:![0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[C_ADDR:%.*]] = alloca [10 x [10 x [10 x i32]]]*, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca i32*, align 8 // CHECK1-NEXT: [[B_ADDR:%.*]] = alloca [10 x [10 x i32]]*, align 8 // CHECK1-NEXT: [[BB_ADDR:%.*]] = alloca i8*, align 8 // CHECK1-NEXT: store [10 x [10 x [10 x i32]]]* [[C]], [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META310:![0-9]+]], metadata !DIExpression()), !dbg [[DBG311:![0-9]+]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x [10 x i32]]]** [[C_ADDR]], metadata [[META337:![0-9]+]], metadata !DIExpression()), !dbg [[DBG338:![0-9]+]] // CHECK1-NEXT: store i32* [[A]], i32** [[A_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META312:![0-9]+]], metadata !DIExpression()), !dbg [[DBG311]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i32** [[A_ADDR]], metadata [[META339:![0-9]+]], metadata !DIExpression()), !dbg [[DBG338]] // CHECK1-NEXT: store [10 x [10 x i32]]* [[B]], [10 x [10 x i32]]** [[B_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META313:![0-9]+]], metadata !DIExpression()), !dbg [[DBG311]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata [10 x [10 x i32]]** [[B_ADDR]], metadata [[META340:![0-9]+]], metadata !DIExpression()), !dbg [[DBG338]] // CHECK1-NEXT: store i8* [[BB]], i8** [[BB_ADDR]], align 8 -// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META314:![0-9]+]], metadata !DIExpression()), !dbg [[DBG311]] -// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG315:![0-9]+]] -// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP4]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i32* [[TMP5]] to i32 addrspace(1)*, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP6]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG315]] -// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast i8* [[TMP7]] to i8 addrspace(1)*, !dbg [[DBG315]] -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP8]], i32 addrspace(1)* [[TMP9]], [10 x [10 x i32]] addrspace(1)* [[TMP10]], i8 addrspace(1)* [[TMP11]]) #[[ATTR3]], !dbg [[DBG315]] -// CHECK1-NEXT: ret void, !dbg [[DBG315]] +// CHECK1-NEXT: call void @llvm.dbg.declare(metadata i8** [[BB_ADDR]], metadata [[META341:![0-9]+]], metadata !DIExpression()), !dbg [[DBG338]] +// CHECK1-NEXT: [[TMP0:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG342:![0-9]+]] +// CHECK1-NEXT: [[TMP1:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP2:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP3:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP4:%.*]] = load [10 x [10 x [10 x i32]]]*, [10 x [10 x [10 x i32]]]** [[C_ADDR]], align 8, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP5:%.*]] = load i32*, i32** [[A_ADDR]], align 8, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP6:%.*]] = load [10 x [10 x i32]]*, [10 x [10 x i32]]** [[B_ADDR]], align 8, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[BB_ADDR]], align 8, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP8:%.*]] = addrspacecast [10 x [10 x [10 x i32]]]* [[TMP4]] to [10 x [10 x [10 x i32]]] addrspace(1)*, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP9:%.*]] = addrspacecast i32* [[TMP5]] to i32 addrspace(1)*, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP10:%.*]] = addrspacecast [10 x [10 x i32]]* [[TMP6]] to [10 x [10 x i32]] addrspace(1)*, !dbg [[DBG342]] +// CHECK1-NEXT: [[TMP11:%.*]] = addrspacecast i8* [[TMP7]] to i8 addrspace(1)*, !dbg [[DBG342]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l41_debug__([10 x [10 x [10 x i32]]] addrspace(1)* [[TMP8]], i32 addrspace(1)* [[TMP9]], [10 x [10 x i32]] addrspace(1)* [[TMP10]], i8 addrspace(1)* [[TMP11]]) #[[ATTR4]], !dbg [[DBG342]] +// CHECK1-NEXT: ret void, !dbg [[DBG342]] // Index: clang/test/OpenMP/target_parallel_for_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/target_parallel_for_reduction_task_codegen.cpp +++ clang/test/OpenMP/target_parallel_for_reduction_task_codegen.cpp @@ -465,61 +465,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -1002,61 +1006,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/target_parallel_for_simd_codegen.cpp =================================================================== --- clang/test/OpenMP/target_parallel_for_simd_codegen.cpp +++ clang/test/OpenMP/target_parallel_for_simd_codegen.cpp @@ -684,22 +684,22 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK1-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK1-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META21]]), !noalias !19 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK1-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !19 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: omp_offload.failed.i: -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]], !noalias !19 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .omp_outlined..1.exit: // CHECK1-NEXT: ret i32 0 @@ -767,32 +767,32 @@ // CHECK1-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !26 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !22 // CHECK1-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK1-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1 // CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 10, [[MUL]] -// CHECK1-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !26 -// CHECK1-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !26 -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK1-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !22 +// CHECK1-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !22 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK1-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3 // CHECK1-NEXT: [[CONV3:%.*]] = sext i32 [[MUL2]] to i64 // CHECK1-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP8]], [[CONV3]] -// CHECK1-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !26 -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !26 +// CHECK1-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !22 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !22 // CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK1-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !26 +// CHECK1-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !22 // 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, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK1-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK1-NEXT: store i32 [[ADD5]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP27:![0-9]+]] +// CHECK1-NEXT: store i32 [[ADD5]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP23:![0-9]+]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK1: omp.dispatch.inc: @@ -905,44 +905,44 @@ // CHECK1-NEXT: store i64 [[TMP6]], i64* [[DOTOMP_IV]], align 8 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK1-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !29 +// CHECK1-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK1-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !25 // CHECK1-NEXT: [[CMP6:%.*]] = icmp ule i64 [[TMP7]], [[TMP8]] // CHECK1-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 +// CHECK1-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 // CHECK1-NEXT: [[MUL:%.*]] = mul i64 [[TMP9]], 400 // CHECK1-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK1-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !29 -// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !29 +// CHECK1-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !25 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !25 // CHECK1-NEXT: [[CONV7:%.*]] = sext i32 [[TMP10]] to i64 -// CHECK1-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK1-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !29 +// CHECK1-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK1-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !25 // CHECK1-NEXT: [[MUL8:%.*]] = mul i64 [[TMP11]], [[TMP12]] // CHECK1-NEXT: [[ADD:%.*]] = add i64 [[CONV7]], [[MUL8]] // CHECK1-NEXT: [[CONV9:%.*]] = trunc i64 [[ADD]] to i32 -// CHECK1-NEXT: store i32 [[CONV9]], i32* [[LIN4]], align 4, !llvm.access.group !29 -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START3]], align 4, !llvm.access.group !29 +// CHECK1-NEXT: store i32 [[CONV9]], i32* [[LIN4]], align 4, !llvm.access.group !25 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START3]], align 4, !llvm.access.group !25 // CHECK1-NEXT: [[CONV10:%.*]] = sext i32 [[TMP13]] to i64 -// CHECK1-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK1-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !29 +// CHECK1-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK1-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !25 // CHECK1-NEXT: [[MUL11:%.*]] = mul i64 [[TMP14]], [[TMP15]] // CHECK1-NEXT: [[ADD12:%.*]] = add i64 [[CONV10]], [[MUL11]] // CHECK1-NEXT: [[CONV13:%.*]] = trunc i64 [[ADD12]] to i32 -// CHECK1-NEXT: store i32 [[CONV13]], i32* [[A5]], align 4, !llvm.access.group !29 -// CHECK1-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 8, !llvm.access.group !29 +// CHECK1-NEXT: store i32 [[CONV13]], i32* [[A5]], align 4, !llvm.access.group !25 +// CHECK1-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 8, !llvm.access.group !25 // CHECK1-NEXT: [[CONV14:%.*]] = sext i16 [[TMP16]] to i32 // CHECK1-NEXT: [[ADD15:%.*]] = add nsw i32 [[CONV14]], 1 // CHECK1-NEXT: [[CONV16:%.*]] = trunc i32 [[ADD15]] to i16 -// CHECK1-NEXT: store i16 [[CONV16]], i16* [[CONV]], align 8, !llvm.access.group !29 +// CHECK1-NEXT: store i16 [[CONV16]], i16* [[CONV]], align 8, !llvm.access.group !25 // 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: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 +// CHECK1-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 // CHECK1-NEXT: [[ADD17:%.*]] = add i64 [[TMP17]], 1 -// CHECK1-NEXT: store i64 [[ADD17]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] +// CHECK1-NEXT: store i64 [[ADD17]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: @@ -1042,32 +1042,32 @@ // CHECK1-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 -// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !32 +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !28 // CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 // CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 4 // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 6, [[MUL]] // CHECK1-NEXT: [[CONV3:%.*]] = trunc i32 [[ADD]] to i16 -// CHECK1-NEXT: store i16 [[CONV3]], i16* [[IT]], align 2, !llvm.access.group !32 -// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !32 +// CHECK1-NEXT: store i16 [[CONV3]], i16* [[IT]], align 2, !llvm.access.group !28 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !28 // CHECK1-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP8]], 1 -// CHECK1-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !32 -// CHECK1-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !32 +// CHECK1-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !28 +// CHECK1-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !28 // CHECK1-NEXT: [[CONV5:%.*]] = sext i16 [[TMP9]] to i32 // CHECK1-NEXT: [[ADD6:%.*]] = add nsw i32 [[CONV5]], 1 // CHECK1-NEXT: [[CONV7:%.*]] = trunc i32 [[ADD6]] to i16 -// CHECK1-NEXT: store i16 [[CONV7]], i16* [[CONV1]], align 8, !llvm.access.group !32 +// CHECK1-NEXT: store i16 [[CONV7]], i16* [[CONV1]], align 8, !llvm.access.group !28 // 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, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 // CHECK1-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK1-NEXT: store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK1-NEXT: store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 +// 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: @@ -1203,60 +1203,60 @@ // CHECK1: omp.dispatch.body: // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !35 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !31 // CHECK1-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]] // CHECK1-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 // CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1 // CHECK1-NEXT: [[SUB:%.*]] = sub nsw i32 122, [[MUL]] // CHECK1-NEXT: [[CONV8:%.*]] = trunc i32 [[SUB]] to i8 -// CHECK1-NEXT: store i8 [[CONV8]], i8* [[IT]], align 1, !llvm.access.group !35 -// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: store i8 [[CONV8]], i8* [[IT]], align 1, !llvm.access.group !31 +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !31 // CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP19]], 1 -// CHECK1-NEXT: store i32 [[ADD]], i32* [[CONV]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: store i32 [[ADD]], i32* [[CONV]], align 8, !llvm.access.group !31 // CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x float], [10 x float]* [[TMP0]], i64 0, i64 2 -// CHECK1-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !35 +// CHECK1-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !31 // CHECK1-NEXT: [[CONV9:%.*]] = fpext float [[TMP20]] to double // CHECK1-NEXT: [[ADD10:%.*]] = fadd double [[CONV9]], 1.000000e+00 // CHECK1-NEXT: [[CONV11:%.*]] = fptrunc double [[ADD10]] to float -// CHECK1-NEXT: store float [[CONV11]], float* [[ARRAYIDX]], align 4, !llvm.access.group !35 +// CHECK1-NEXT: store float [[CONV11]], float* [[ARRAYIDX]], align 4, !llvm.access.group !31 // CHECK1-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds float, float* [[TMP2]], i64 3 -// CHECK1-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX12]], align 4, !llvm.access.group !35 +// CHECK1-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX12]], align 4, !llvm.access.group !31 // CHECK1-NEXT: [[CONV13:%.*]] = fpext float [[TMP21]] to double // CHECK1-NEXT: [[ADD14:%.*]] = fadd double [[CONV13]], 1.000000e+00 // CHECK1-NEXT: [[CONV15:%.*]] = fptrunc double [[ADD14]] to float -// CHECK1-NEXT: store float [[CONV15]], float* [[ARRAYIDX12]], align 4, !llvm.access.group !35 +// CHECK1-NEXT: store float [[CONV15]], float* [[ARRAYIDX12]], align 4, !llvm.access.group !31 // CHECK1-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[TMP3]], i64 0, i64 1 // CHECK1-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x double], [10 x double]* [[ARRAYIDX16]], i64 0, i64 2 -// CHECK1-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX17]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX17]], align 8, !llvm.access.group !31 // CHECK1-NEXT: [[ADD18:%.*]] = fadd double [[TMP22]], 1.000000e+00 -// CHECK1-NEXT: store double [[ADD18]], double* [[ARRAYIDX17]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: store double [[ADD18]], double* [[ARRAYIDX17]], align 8, !llvm.access.group !31 // CHECK1-NEXT: [[TMP23:%.*]] = mul nsw i64 1, [[TMP5]] // CHECK1-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds double, double* [[TMP6]], i64 [[TMP23]] // CHECK1-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX19]], i64 3 -// CHECK1-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX20]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX20]], align 8, !llvm.access.group !31 // CHECK1-NEXT: [[ADD21:%.*]] = fadd double [[TMP24]], 1.000000e+00 -// CHECK1-NEXT: store double [[ADD21]], double* [[ARRAYIDX20]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: store double [[ADD21]], double* [[ARRAYIDX20]], align 8, !llvm.access.group !31 // CHECK1-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_TT:%.*]], %struct.TT* [[TMP7]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 8, !llvm.access.group !31 // CHECK1-NEXT: [[ADD22:%.*]] = add nsw i64 [[TMP25]], 1 -// CHECK1-NEXT: store i64 [[ADD22]], i64* [[X]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: store i64 [[ADD22]], i64* [[X]], align 8, !llvm.access.group !31 // CHECK1-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_TT]], %struct.TT* [[TMP7]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 8, !llvm.access.group !31 // CHECK1-NEXT: [[CONV23:%.*]] = sext i8 [[TMP26]] to i32 // CHECK1-NEXT: [[ADD24:%.*]] = add nsw i32 [[CONV23]], 1 // CHECK1-NEXT: [[CONV25:%.*]] = trunc i32 [[ADD24]] to i8 -// CHECK1-NEXT: store i8 [[CONV25]], i8* [[Y]], align 8, !llvm.access.group !35 +// CHECK1-NEXT: store i8 [[CONV25]], i8* [[Y]], align 8, !llvm.access.group !31 // 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: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 +// CHECK1-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 // CHECK1-NEXT: [[ADD26:%.*]] = add nsw i32 [[TMP27]], 1 -// CHECK1-NEXT: store i32 [[ADD26]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] +// CHECK1-NEXT: store i32 [[ADD26]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP32:![0-9]+]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK1: omp.dispatch.inc: @@ -1658,37 +1658,37 @@ // CHECK1-NEXT: store i64 [[TMP8]], i64* [[DOTOMP_IV]], align 8 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 -// CHECK1-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !38 +// CHECK1-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 +// CHECK1-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !34 // CHECK1-NEXT: [[CMP3:%.*]] = icmp ule i64 [[TMP9]], [[TMP10]] // CHECK1-NEXT: br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK1-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 // CHECK1-NEXT: [[MUL:%.*]] = mul i64 [[TMP11]], 400 // CHECK1-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK1-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !38 -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !38 +// CHECK1-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !34 +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !34 // CHECK1-NEXT: [[CONV4:%.*]] = sitofp i32 [[TMP12]] to double // CHECK1-NEXT: [[ADD:%.*]] = fadd double [[CONV4]], 1.500000e+00 // CHECK1-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK1-NEXT: store double [[ADD]], double* [[A]], align 8, !llvm.access.group !38 +// CHECK1-NEXT: store double [[ADD]], double* [[A]], align 8, !llvm.access.group !34 // CHECK1-NEXT: [[A5:%.*]] = getelementptr inbounds [[STRUCT_S1]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP13:%.*]] = load double, double* [[A5]], align 8, !llvm.access.group !38 +// CHECK1-NEXT: [[TMP13:%.*]] = load double, double* [[A5]], align 8, !llvm.access.group !34 // CHECK1-NEXT: [[INC:%.*]] = fadd double [[TMP13]], 1.000000e+00 -// CHECK1-NEXT: store double [[INC]], double* [[A5]], align 8, !llvm.access.group !38 +// CHECK1-NEXT: store double [[INC]], double* [[A5]], align 8, !llvm.access.group !34 // CHECK1-NEXT: [[CONV6:%.*]] = fptosi double [[INC]] to i16 // CHECK1-NEXT: [[TMP14:%.*]] = mul nsw i64 1, [[TMP2]] // CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, i16* [[TMP3]], i64 [[TMP14]] // CHECK1-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i16, i16* [[ARRAYIDX]], i64 1 -// CHECK1-NEXT: store i16 [[CONV6]], i16* [[ARRAYIDX7]], align 2, !llvm.access.group !38 +// CHECK1-NEXT: store i16 [[CONV6]], i16* [[ARRAYIDX7]], align 2, !llvm.access.group !34 // 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: [[TMP15:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK1-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 // CHECK1-NEXT: [[ADD8:%.*]] = add i64 [[TMP15]], 1 -// CHECK1-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP39:![0-9]+]] +// CHECK1-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP35:![0-9]+]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: @@ -1832,35 +1832,35 @@ // CHECK1-NEXT: store i64 [[TMP5]], i64* [[DOTOMP_IV]], align 8 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK1: omp.inner.for.cond: -// CHECK1-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 -// CHECK1-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !41 +// CHECK1-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !37 +// CHECK1-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !37 // CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i64 [[TMP6]], [[TMP7]] // CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK1: omp.inner.for.body: -// CHECK1-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 +// CHECK1-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !37 // CHECK1-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP8]], 3 // CHECK1-NEXT: [[ADD:%.*]] = add nsw i64 -10, [[MUL]] -// CHECK1-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !41 -// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !41 +// CHECK1-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !37 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !37 // CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP9]], 1 -// CHECK1-NEXT: store i32 [[ADD3]], i32* [[CONV]], align 8, !llvm.access.group !41 -// CHECK1-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !41 +// CHECK1-NEXT: store i32 [[ADD3]], i32* [[CONV]], align 8, !llvm.access.group !37 +// CHECK1-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !37 // CHECK1-NEXT: [[CONV4:%.*]] = sext i16 [[TMP10]] to i32 // CHECK1-NEXT: [[ADD5:%.*]] = add nsw i32 [[CONV4]], 1 // CHECK1-NEXT: [[CONV6:%.*]] = trunc i32 [[ADD5]] to i16 -// CHECK1-NEXT: store i16 [[CONV6]], i16* [[CONV1]], align 8, !llvm.access.group !41 +// CHECK1-NEXT: store i16 [[CONV6]], i16* [[CONV1]], align 8, !llvm.access.group !37 // CHECK1-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[TMP0]], i64 0, i64 2 -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !41 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !37 // CHECK1-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK1-NEXT: store i32 [[ADD7]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !41 +// CHECK1-NEXT: store i32 [[ADD7]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !37 // 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: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 +// CHECK1-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !37 // CHECK1-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP12]], 1 -// CHECK1-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 -// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP42:![0-9]+]] +// CHECK1-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !37 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP38:![0-9]+]] // CHECK1: omp.inner.for.end: // CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK1: omp.loop.exit: @@ -2273,22 +2273,22 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !25 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !25 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !25 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !25 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK2-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK2-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK2-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META21]]), !noalias !19 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK2-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !19 +// CHECK2-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK2-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: omp_offload.failed.i: -// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]] +// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]], !noalias !19 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .omp_outlined..1.exit: // CHECK2-NEXT: ret i32 0 @@ -2356,32 +2356,32 @@ // CHECK2-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 -// CHECK2-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !26 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !22 // CHECK2-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK2-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1 // CHECK2-NEXT: [[SUB:%.*]] = sub nsw i32 10, [[MUL]] -// CHECK2-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !26 -// CHECK2-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !26 -// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK2-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !22 +// CHECK2-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !22 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK2-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3 // CHECK2-NEXT: [[CONV3:%.*]] = sext i32 [[MUL2]] to i64 // CHECK2-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP8]], [[CONV3]] -// CHECK2-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !26 -// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !26 +// CHECK2-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !22 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !22 // CHECK2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK2-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !26 +// CHECK2-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !22 // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK2-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK2-NEXT: store i32 [[ADD5]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP27:![0-9]+]] +// CHECK2-NEXT: store i32 [[ADD5]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP23:![0-9]+]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK2: omp.dispatch.inc: @@ -2494,44 +2494,44 @@ // CHECK2-NEXT: store i64 [[TMP6]], i64* [[DOTOMP_IV]], align 8 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK2-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !29 +// CHECK2-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK2-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !25 // CHECK2-NEXT: [[CMP6:%.*]] = icmp ule i64 [[TMP7]], [[TMP8]] // CHECK2-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 +// CHECK2-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 // CHECK2-NEXT: [[MUL:%.*]] = mul i64 [[TMP9]], 400 // CHECK2-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK2-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !29 -// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !29 +// CHECK2-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !25 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !25 // CHECK2-NEXT: [[CONV7:%.*]] = sext i32 [[TMP10]] to i64 -// CHECK2-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK2-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !29 +// CHECK2-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK2-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !25 // CHECK2-NEXT: [[MUL8:%.*]] = mul i64 [[TMP11]], [[TMP12]] // CHECK2-NEXT: [[ADD:%.*]] = add i64 [[CONV7]], [[MUL8]] // CHECK2-NEXT: [[CONV9:%.*]] = trunc i64 [[ADD]] to i32 -// CHECK2-NEXT: store i32 [[CONV9]], i32* [[LIN4]], align 4, !llvm.access.group !29 -// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START3]], align 4, !llvm.access.group !29 +// CHECK2-NEXT: store i32 [[CONV9]], i32* [[LIN4]], align 4, !llvm.access.group !25 +// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START3]], align 4, !llvm.access.group !25 // CHECK2-NEXT: [[CONV10:%.*]] = sext i32 [[TMP13]] to i64 -// CHECK2-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK2-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !29 +// CHECK2-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK2-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !25 // CHECK2-NEXT: [[MUL11:%.*]] = mul i64 [[TMP14]], [[TMP15]] // CHECK2-NEXT: [[ADD12:%.*]] = add i64 [[CONV10]], [[MUL11]] // CHECK2-NEXT: [[CONV13:%.*]] = trunc i64 [[ADD12]] to i32 -// CHECK2-NEXT: store i32 [[CONV13]], i32* [[A5]], align 4, !llvm.access.group !29 -// CHECK2-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 8, !llvm.access.group !29 +// CHECK2-NEXT: store i32 [[CONV13]], i32* [[A5]], align 4, !llvm.access.group !25 +// CHECK2-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 8, !llvm.access.group !25 // CHECK2-NEXT: [[CONV14:%.*]] = sext i16 [[TMP16]] to i32 // CHECK2-NEXT: [[ADD15:%.*]] = add nsw i32 [[CONV14]], 1 // CHECK2-NEXT: [[CONV16:%.*]] = trunc i32 [[ADD15]] to i16 -// CHECK2-NEXT: store i16 [[CONV16]], i16* [[CONV]], align 8, !llvm.access.group !29 +// CHECK2-NEXT: store i16 [[CONV16]], i16* [[CONV]], align 8, !llvm.access.group !25 // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 +// CHECK2-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 // CHECK2-NEXT: [[ADD17:%.*]] = add i64 [[TMP17]], 1 -// CHECK2-NEXT: store i64 [[ADD17]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] +// CHECK2-NEXT: store i64 [[ADD17]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: @@ -2631,32 +2631,32 @@ // CHECK2-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 -// CHECK2-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !32 +// CHECK2-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 +// CHECK2-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !28 // CHECK2-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK2-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK2-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 // CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 4 // CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 6, [[MUL]] // CHECK2-NEXT: [[CONV3:%.*]] = trunc i32 [[ADD]] to i16 -// CHECK2-NEXT: store i16 [[CONV3]], i16* [[IT]], align 2, !llvm.access.group !32 -// CHECK2-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !32 +// CHECK2-NEXT: store i16 [[CONV3]], i16* [[IT]], align 2, !llvm.access.group !28 +// CHECK2-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !28 // CHECK2-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP8]], 1 -// CHECK2-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !32 -// CHECK2-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !32 +// CHECK2-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !28 +// CHECK2-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !28 // CHECK2-NEXT: [[CONV5:%.*]] = sext i16 [[TMP9]] to i32 // CHECK2-NEXT: [[ADD6:%.*]] = add nsw i32 [[CONV5]], 1 // CHECK2-NEXT: [[CONV7:%.*]] = trunc i32 [[ADD6]] to i16 -// CHECK2-NEXT: store i16 [[CONV7]], i16* [[CONV1]], align 8, !llvm.access.group !32 +// CHECK2-NEXT: store i16 [[CONV7]], i16* [[CONV1]], align 8, !llvm.access.group !28 // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK2-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 // CHECK2-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK2-NEXT: store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK2-NEXT: store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: @@ -2792,60 +2792,60 @@ // CHECK2: omp.dispatch.body: // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 -// CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !35 +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 +// CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !31 // CHECK2-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]] // CHECK2-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 +// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 // CHECK2-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1 // CHECK2-NEXT: [[SUB:%.*]] = sub nsw i32 122, [[MUL]] // CHECK2-NEXT: [[CONV8:%.*]] = trunc i32 [[SUB]] to i8 -// CHECK2-NEXT: store i8 [[CONV8]], i8* [[IT]], align 1, !llvm.access.group !35 -// CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: store i8 [[CONV8]], i8* [[IT]], align 1, !llvm.access.group !31 +// CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !31 // CHECK2-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP19]], 1 -// CHECK2-NEXT: store i32 [[ADD]], i32* [[CONV]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: store i32 [[ADD]], i32* [[CONV]], align 8, !llvm.access.group !31 // CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x float], [10 x float]* [[TMP0]], i64 0, i64 2 -// CHECK2-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !35 +// CHECK2-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !31 // CHECK2-NEXT: [[CONV9:%.*]] = fpext float [[TMP20]] to double // CHECK2-NEXT: [[ADD10:%.*]] = fadd double [[CONV9]], 1.000000e+00 // CHECK2-NEXT: [[CONV11:%.*]] = fptrunc double [[ADD10]] to float -// CHECK2-NEXT: store float [[CONV11]], float* [[ARRAYIDX]], align 4, !llvm.access.group !35 +// CHECK2-NEXT: store float [[CONV11]], float* [[ARRAYIDX]], align 4, !llvm.access.group !31 // CHECK2-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds float, float* [[TMP2]], i64 3 -// CHECK2-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX12]], align 4, !llvm.access.group !35 +// CHECK2-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX12]], align 4, !llvm.access.group !31 // CHECK2-NEXT: [[CONV13:%.*]] = fpext float [[TMP21]] to double // CHECK2-NEXT: [[ADD14:%.*]] = fadd double [[CONV13]], 1.000000e+00 // CHECK2-NEXT: [[CONV15:%.*]] = fptrunc double [[ADD14]] to float -// CHECK2-NEXT: store float [[CONV15]], float* [[ARRAYIDX12]], align 4, !llvm.access.group !35 +// CHECK2-NEXT: store float [[CONV15]], float* [[ARRAYIDX12]], align 4, !llvm.access.group !31 // CHECK2-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[TMP3]], i64 0, i64 1 // CHECK2-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x double], [10 x double]* [[ARRAYIDX16]], i64 0, i64 2 -// CHECK2-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX17]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX17]], align 8, !llvm.access.group !31 // CHECK2-NEXT: [[ADD18:%.*]] = fadd double [[TMP22]], 1.000000e+00 -// CHECK2-NEXT: store double [[ADD18]], double* [[ARRAYIDX17]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: store double [[ADD18]], double* [[ARRAYIDX17]], align 8, !llvm.access.group !31 // CHECK2-NEXT: [[TMP23:%.*]] = mul nsw i64 1, [[TMP5]] // CHECK2-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds double, double* [[TMP6]], i64 [[TMP23]] // CHECK2-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX19]], i64 3 -// CHECK2-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX20]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX20]], align 8, !llvm.access.group !31 // CHECK2-NEXT: [[ADD21:%.*]] = fadd double [[TMP24]], 1.000000e+00 -// CHECK2-NEXT: store double [[ADD21]], double* [[ARRAYIDX20]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: store double [[ADD21]], double* [[ARRAYIDX20]], align 8, !llvm.access.group !31 // CHECK2-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_TT:%.*]], %struct.TT* [[TMP7]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 8, !llvm.access.group !31 // CHECK2-NEXT: [[ADD22:%.*]] = add nsw i64 [[TMP25]], 1 -// CHECK2-NEXT: store i64 [[ADD22]], i64* [[X]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: store i64 [[ADD22]], i64* [[X]], align 8, !llvm.access.group !31 // CHECK2-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_TT]], %struct.TT* [[TMP7]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 8, !llvm.access.group !31 // CHECK2-NEXT: [[CONV23:%.*]] = sext i8 [[TMP26]] to i32 // CHECK2-NEXT: [[ADD24:%.*]] = add nsw i32 [[CONV23]], 1 // CHECK2-NEXT: [[CONV25:%.*]] = trunc i32 [[ADD24]] to i8 -// CHECK2-NEXT: store i8 [[CONV25]], i8* [[Y]], align 8, !llvm.access.group !35 +// CHECK2-NEXT: store i8 [[CONV25]], i8* [[Y]], align 8, !llvm.access.group !31 // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 +// CHECK2-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 // CHECK2-NEXT: [[ADD26:%.*]] = add nsw i32 [[TMP27]], 1 -// CHECK2-NEXT: store i32 [[ADD26]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] +// CHECK2-NEXT: store i32 [[ADD26]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP32:![0-9]+]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK2: omp.dispatch.inc: @@ -3247,37 +3247,37 @@ // CHECK2-NEXT: store i64 [[TMP8]], i64* [[DOTOMP_IV]], align 8 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 -// CHECK2-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !38 +// CHECK2-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 +// CHECK2-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !34 // CHECK2-NEXT: [[CMP3:%.*]] = icmp ule i64 [[TMP9]], [[TMP10]] // CHECK2-NEXT: br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK2-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 // CHECK2-NEXT: [[MUL:%.*]] = mul i64 [[TMP11]], 400 // CHECK2-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK2-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !38 -// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !38 +// CHECK2-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !34 +// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !34 // CHECK2-NEXT: [[CONV4:%.*]] = sitofp i32 [[TMP12]] to double // CHECK2-NEXT: [[ADD:%.*]] = fadd double [[CONV4]], 1.500000e+00 // CHECK2-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK2-NEXT: store double [[ADD]], double* [[A]], align 8, !llvm.access.group !38 +// CHECK2-NEXT: store double [[ADD]], double* [[A]], align 8, !llvm.access.group !34 // CHECK2-NEXT: [[A5:%.*]] = getelementptr inbounds [[STRUCT_S1]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP13:%.*]] = load double, double* [[A5]], align 8, !llvm.access.group !38 +// CHECK2-NEXT: [[TMP13:%.*]] = load double, double* [[A5]], align 8, !llvm.access.group !34 // CHECK2-NEXT: [[INC:%.*]] = fadd double [[TMP13]], 1.000000e+00 -// CHECK2-NEXT: store double [[INC]], double* [[A5]], align 8, !llvm.access.group !38 +// CHECK2-NEXT: store double [[INC]], double* [[A5]], align 8, !llvm.access.group !34 // CHECK2-NEXT: [[CONV6:%.*]] = fptosi double [[INC]] to i16 // CHECK2-NEXT: [[TMP14:%.*]] = mul nsw i64 1, [[TMP2]] // CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, i16* [[TMP3]], i64 [[TMP14]] // CHECK2-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i16, i16* [[ARRAYIDX]], i64 1 -// CHECK2-NEXT: store i16 [[CONV6]], i16* [[ARRAYIDX7]], align 2, !llvm.access.group !38 +// CHECK2-NEXT: store i16 [[CONV6]], i16* [[ARRAYIDX7]], align 2, !llvm.access.group !34 // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK2-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 // CHECK2-NEXT: [[ADD8:%.*]] = add i64 [[TMP15]], 1 -// CHECK2-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP39:![0-9]+]] +// CHECK2-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP35:![0-9]+]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: @@ -3421,35 +3421,35 @@ // CHECK2-NEXT: store i64 [[TMP5]], i64* [[DOTOMP_IV]], align 8 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK2: omp.inner.for.cond: -// CHECK2-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 -// CHECK2-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !41 +// CHECK2-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !37 +// CHECK2-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !37 // CHECK2-NEXT: [[CMP2:%.*]] = icmp sle i64 [[TMP6]], [[TMP7]] // CHECK2-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK2: omp.inner.for.body: -// CHECK2-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 +// CHECK2-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !37 // CHECK2-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP8]], 3 // CHECK2-NEXT: [[ADD:%.*]] = add nsw i64 -10, [[MUL]] -// CHECK2-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !41 -// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !41 +// CHECK2-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !37 +// CHECK2-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !37 // CHECK2-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP9]], 1 -// CHECK2-NEXT: store i32 [[ADD3]], i32* [[CONV]], align 8, !llvm.access.group !41 -// CHECK2-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !41 +// CHECK2-NEXT: store i32 [[ADD3]], i32* [[CONV]], align 8, !llvm.access.group !37 +// CHECK2-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !37 // CHECK2-NEXT: [[CONV4:%.*]] = sext i16 [[TMP10]] to i32 // CHECK2-NEXT: [[ADD5:%.*]] = add nsw i32 [[CONV4]], 1 // CHECK2-NEXT: [[CONV6:%.*]] = trunc i32 [[ADD5]] to i16 -// CHECK2-NEXT: store i16 [[CONV6]], i16* [[CONV1]], align 8, !llvm.access.group !41 +// CHECK2-NEXT: store i16 [[CONV6]], i16* [[CONV1]], align 8, !llvm.access.group !37 // CHECK2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[TMP0]], i64 0, i64 2 -// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !41 +// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !37 // CHECK2-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK2-NEXT: store i32 [[ADD7]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !41 +// CHECK2-NEXT: store i32 [[ADD7]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !37 // CHECK2-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK2: omp.body.continue: // CHECK2-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK2: omp.inner.for.inc: -// CHECK2-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 +// CHECK2-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !37 // CHECK2-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP12]], 1 -// CHECK2-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 -// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP42:![0-9]+]] +// CHECK2-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !37 +// CHECK2-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP38:![0-9]+]] // CHECK2: omp.inner.for.end: // CHECK2-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK2: omp.loop.exit: @@ -3852,22 +3852,22 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 4 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK3-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK3-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META22]]), !noalias !20 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !20 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !20 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !20 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !20 +// CHECK3-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !20 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !20 +// CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !20 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK3: omp_offload.failed.i: -// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]], !noalias !20 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK3: .omp_outlined..1.exit: // CHECK3-NEXT: ret i32 0 @@ -3930,32 +3930,32 @@ // CHECK3-NEXT: store i32 [[TMP5]], i32* [[DOTOMP_IV]], align 4 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 -// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !27 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !23 // CHECK3-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] // CHECK3-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK3: omp.inner.for.body: -// CHECK3-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP8]], 1 // CHECK3-NEXT: [[SUB:%.*]] = sub nsw i32 10, [[MUL]] -// CHECK3-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !27 -// CHECK3-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !27 -// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK3-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !23 +// CHECK3-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !23 +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK3-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP10]], 3 // CHECK3-NEXT: [[CONV:%.*]] = sext i32 [[MUL2]] to i64 // CHECK3-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP9]], [[CONV]] -// CHECK3-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !27 -// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !27 +// CHECK3-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !23 +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !23 // CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK3-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !27 +// CHECK3-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !23 // 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: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK3-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP12]], 1 -// CHECK3-NEXT: store i32 [[ADD4]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK3-NEXT: store i32 [[ADD4]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK3: omp.dispatch.inc: @@ -4062,44 +4062,44 @@ // CHECK3-NEXT: store i64 [[TMP6]], i64* [[DOTOMP_IV]], align 8 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK3-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !30 +// CHECK3-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK3-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !26 // CHECK3-NEXT: [[CMP4:%.*]] = icmp ule i64 [[TMP7]], [[TMP8]] // CHECK3-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK3: omp.inner.for.body: -// CHECK3-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 +// CHECK3-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 // CHECK3-NEXT: [[MUL:%.*]] = mul i64 [[TMP9]], 400 // CHECK3-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK3-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !30 -// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !30 +// CHECK3-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !26 +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !26 // CHECK3-NEXT: [[CONV5:%.*]] = sext i32 [[TMP10]] to i64 -// CHECK3-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK3-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !30 +// CHECK3-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK3-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !26 // CHECK3-NEXT: [[MUL6:%.*]] = mul i64 [[TMP11]], [[TMP12]] // CHECK3-NEXT: [[ADD:%.*]] = add i64 [[CONV5]], [[MUL6]] // CHECK3-NEXT: [[CONV7:%.*]] = trunc i64 [[ADD]] to i32 -// CHECK3-NEXT: store i32 [[CONV7]], i32* [[LIN2]], align 4, !llvm.access.group !30 -// CHECK3-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4, !llvm.access.group !30 +// CHECK3-NEXT: store i32 [[CONV7]], i32* [[LIN2]], align 4, !llvm.access.group !26 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4, !llvm.access.group !26 // CHECK3-NEXT: [[CONV8:%.*]] = sext i32 [[TMP13]] to i64 -// CHECK3-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK3-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !30 +// CHECK3-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK3-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !26 // CHECK3-NEXT: [[MUL9:%.*]] = mul i64 [[TMP14]], [[TMP15]] // CHECK3-NEXT: [[ADD10:%.*]] = add i64 [[CONV8]], [[MUL9]] // CHECK3-NEXT: [[CONV11:%.*]] = trunc i64 [[ADD10]] to i32 -// CHECK3-NEXT: store i32 [[CONV11]], i32* [[A3]], align 4, !llvm.access.group !30 -// CHECK3-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !30 +// CHECK3-NEXT: store i32 [[CONV11]], i32* [[A3]], align 4, !llvm.access.group !26 +// CHECK3-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !26 // CHECK3-NEXT: [[CONV12:%.*]] = sext i16 [[TMP16]] to i32 // CHECK3-NEXT: [[ADD13:%.*]] = add nsw i32 [[CONV12]], 1 // CHECK3-NEXT: [[CONV14:%.*]] = trunc i32 [[ADD13]] to i16 -// CHECK3-NEXT: store i16 [[CONV14]], i16* [[CONV]], align 4, !llvm.access.group !30 +// CHECK3-NEXT: store i16 [[CONV14]], i16* [[CONV]], align 4, !llvm.access.group !26 // 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: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 +// CHECK3-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 // CHECK3-NEXT: [[ADD15:%.*]] = add i64 [[TMP17]], 1 -// CHECK3-NEXT: store i64 [[ADD15]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK3-NEXT: store i64 [[ADD15]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP27:![0-9]+]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: @@ -4196,32 +4196,32 @@ // CHECK3-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 -// CHECK3-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !33 +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !29 // 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, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 // CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 4 // CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 6, [[MUL]] // CHECK3-NEXT: [[CONV2:%.*]] = trunc i32 [[ADD]] to i16 -// CHECK3-NEXT: store i16 [[CONV2]], i16* [[IT]], align 2, !llvm.access.group !33 -// CHECK3-NEXT: [[TMP8:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !33 +// CHECK3-NEXT: store i16 [[CONV2]], i16* [[IT]], align 2, !llvm.access.group !29 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !29 // CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], 1 -// CHECK3-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !33 -// CHECK3-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !33 +// CHECK3-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !29 +// CHECK3-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !29 // CHECK3-NEXT: [[CONV4:%.*]] = sext i16 [[TMP9]] to i32 // CHECK3-NEXT: [[ADD5:%.*]] = add nsw i32 [[CONV4]], 1 // CHECK3-NEXT: [[CONV6:%.*]] = trunc i32 [[ADD5]] to i16 -// CHECK3-NEXT: store i16 [[CONV6]], i16* [[CONV]], align 4, !llvm.access.group !33 +// CHECK3-NEXT: store i16 [[CONV6]], i16* [[CONV]], align 4, !llvm.access.group !29 // 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, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 // CHECK3-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK3-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK3-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: @@ -4351,60 +4351,60 @@ // CHECK3: omp.dispatch.body: // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 -// CHECK3-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]] // CHECK3-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK3: omp.inner.for.body: -// CHECK3-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1 // CHECK3-NEXT: [[SUB:%.*]] = sub nsw i32 122, [[MUL]] // CHECK3-NEXT: [[CONV:%.*]] = trunc i32 [[SUB]] to i8 -// CHECK3-NEXT: store i8 [[CONV]], i8* [[IT]], align 1, !llvm.access.group !36 -// CHECK3-NEXT: [[TMP19:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: store i8 [[CONV]], i8* [[IT]], align 1, !llvm.access.group !32 +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP19]], 1 -// CHECK3-NEXT: store i32 [[ADD]], i32* [[A_ADDR]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: store i32 [[ADD]], i32* [[A_ADDR]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x float], [10 x float]* [[TMP0]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[CONV7:%.*]] = fpext float [[TMP20]] to double // CHECK3-NEXT: [[ADD8:%.*]] = fadd double [[CONV7]], 1.000000e+00 // CHECK3-NEXT: [[CONV9:%.*]] = fptrunc double [[ADD8]] to float -// CHECK3-NEXT: store float [[CONV9]], float* [[ARRAYIDX]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: store float [[CONV9]], float* [[ARRAYIDX]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, float* [[TMP2]], i32 3 -// CHECK3-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX10]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX10]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[CONV11:%.*]] = fpext float [[TMP21]] to double // CHECK3-NEXT: [[ADD12:%.*]] = fadd double [[CONV11]], 1.000000e+00 // CHECK3-NEXT: [[CONV13:%.*]] = fptrunc double [[ADD12]] to float -// CHECK3-NEXT: store float [[CONV13]], float* [[ARRAYIDX10]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: store float [[CONV13]], float* [[ARRAYIDX10]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[TMP3]], i32 0, i32 1 // CHECK3-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x double], [10 x double]* [[ARRAYIDX14]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX15]], align 8, !llvm.access.group !36 +// CHECK3-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX15]], align 8, !llvm.access.group !32 // CHECK3-NEXT: [[ADD16:%.*]] = fadd double [[TMP22]], 1.000000e+00 -// CHECK3-NEXT: store double [[ADD16]], double* [[ARRAYIDX15]], align 8, !llvm.access.group !36 +// CHECK3-NEXT: store double [[ADD16]], double* [[ARRAYIDX15]], align 8, !llvm.access.group !32 // CHECK3-NEXT: [[TMP23:%.*]] = mul nsw i32 1, [[TMP5]] // CHECK3-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds double, double* [[TMP6]], i32 [[TMP23]] // CHECK3-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX17]], i32 3 -// CHECK3-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX18]], align 8, !llvm.access.group !36 +// CHECK3-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX18]], align 8, !llvm.access.group !32 // CHECK3-NEXT: [[ADD19:%.*]] = fadd double [[TMP24]], 1.000000e+00 -// CHECK3-NEXT: store double [[ADD19]], double* [[ARRAYIDX18]], align 8, !llvm.access.group !36 +// CHECK3-NEXT: store double [[ADD19]], double* [[ARRAYIDX18]], align 8, !llvm.access.group !32 // CHECK3-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_TT:%.*]], %struct.TT* [[TMP7]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[ADD20:%.*]] = add nsw i64 [[TMP25]], 1 -// CHECK3-NEXT: store i64 [[ADD20]], i64* [[X]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: store i64 [[ADD20]], i64* [[X]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_TT]], %struct.TT* [[TMP7]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[CONV21:%.*]] = sext i8 [[TMP26]] to i32 // CHECK3-NEXT: [[ADD22:%.*]] = add nsw i32 [[CONV21]], 1 // CHECK3-NEXT: [[CONV23:%.*]] = trunc i32 [[ADD22]] to i8 -// CHECK3-NEXT: store i8 [[CONV23]], i8* [[Y]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: store i8 [[CONV23]], i8* [[Y]], align 4, !llvm.access.group !32 // 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: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 +// CHECK3-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 // CHECK3-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP27]], 1 -// CHECK3-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK3-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK3: omp.dispatch.inc: @@ -4800,37 +4800,37 @@ // CHECK3-NEXT: store i64 [[TMP8]], i64* [[DOTOMP_IV]], align 8 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 -// CHECK3-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !39 +// CHECK3-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 +// CHECK3-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !35 // CHECK3-NEXT: [[CMP3:%.*]] = icmp ule i64 [[TMP9]], [[TMP10]] // CHECK3-NEXT: br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK3: omp.inner.for.body: -// CHECK3-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 +// CHECK3-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 // CHECK3-NEXT: [[MUL:%.*]] = mul i64 [[TMP11]], 400 // CHECK3-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK3-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !39 -// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[B_ADDR]], align 4, !llvm.access.group !39 +// CHECK3-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !35 +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[B_ADDR]], align 4, !llvm.access.group !35 // CHECK3-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP12]] to double // CHECK3-NEXT: [[ADD:%.*]] = fadd double [[CONV]], 1.500000e+00 // CHECK3-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK3-NEXT: store double [[ADD]], double* [[A]], align 4, !llvm.access.group !39 +// CHECK3-NEXT: store double [[ADD]], double* [[A]], align 4, !llvm.access.group !35 // CHECK3-NEXT: [[A4:%.*]] = getelementptr inbounds [[STRUCT_S1]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP13:%.*]] = load double, double* [[A4]], align 4, !llvm.access.group !39 +// CHECK3-NEXT: [[TMP13:%.*]] = load double, double* [[A4]], align 4, !llvm.access.group !35 // CHECK3-NEXT: [[INC:%.*]] = fadd double [[TMP13]], 1.000000e+00 -// CHECK3-NEXT: store double [[INC]], double* [[A4]], align 4, !llvm.access.group !39 +// CHECK3-NEXT: store double [[INC]], double* [[A4]], align 4, !llvm.access.group !35 // CHECK3-NEXT: [[CONV5:%.*]] = fptosi double [[INC]] to i16 // CHECK3-NEXT: [[TMP14:%.*]] = mul nsw i32 1, [[TMP2]] // CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, i16* [[TMP3]], i32 [[TMP14]] // CHECK3-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i16, i16* [[ARRAYIDX]], i32 1 -// CHECK3-NEXT: store i16 [[CONV5]], i16* [[ARRAYIDX6]], align 2, !llvm.access.group !39 +// CHECK3-NEXT: store i16 [[CONV5]], i16* [[ARRAYIDX6]], align 2, !llvm.access.group !35 // 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: [[TMP15:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 +// CHECK3-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 // CHECK3-NEXT: [[ADD7:%.*]] = add i64 [[TMP15]], 1 -// CHECK3-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK3-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: @@ -4968,35 +4968,35 @@ // CHECK3-NEXT: store i64 [[TMP5]], i64* [[DOTOMP_IV]], align 8 // CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK3: omp.inner.for.cond: -// CHECK3-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !42 -// CHECK3-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !42 +// CHECK3-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK3-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !38 // CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i64 [[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 i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !42 +// CHECK3-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 // CHECK3-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP8]], 3 // CHECK3-NEXT: [[ADD:%.*]] = add nsw i64 -10, [[MUL]] -// CHECK3-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !42 -// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !42 +// CHECK3-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !38 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !38 // CHECK3-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1 -// CHECK3-NEXT: store i32 [[ADD2]], i32* [[A_ADDR]], align 4, !llvm.access.group !42 -// CHECK3-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !42 +// CHECK3-NEXT: store i32 [[ADD2]], i32* [[A_ADDR]], align 4, !llvm.access.group !38 +// CHECK3-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !38 // CHECK3-NEXT: [[CONV3:%.*]] = sext i16 [[TMP10]] to i32 // CHECK3-NEXT: [[ADD4:%.*]] = add nsw i32 [[CONV3]], 1 // CHECK3-NEXT: [[CONV5:%.*]] = trunc i32 [[ADD4]] to i16 -// CHECK3-NEXT: store i16 [[CONV5]], i16* [[CONV]], align 4, !llvm.access.group !42 +// CHECK3-NEXT: store i16 [[CONV5]], i16* [[CONV]], align 4, !llvm.access.group !38 // CHECK3-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[TMP0]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !42 +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !38 // CHECK3-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK3-NEXT: store i32 [[ADD6]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !42 +// CHECK3-NEXT: store i32 [[ADD6]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !38 // 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: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !42 +// CHECK3-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 // CHECK3-NEXT: [[ADD7:%.*]] = add nsw i64 [[TMP12]], 1 -// CHECK3-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !42 -// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK3-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP39:![0-9]+]] // CHECK3: omp.inner.for.end: // CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK3: omp.loop.exit: @@ -5399,22 +5399,22 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 4 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !26 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !26 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !26 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !26 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK4-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK4-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK4-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META22]]), !noalias !20 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !20 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !20 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !20 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !20 +// CHECK4-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !20 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !20 +// CHECK4-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !20 +// CHECK4-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK4-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK4: omp_offload.failed.i: -// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]] +// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]], !noalias !20 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK4: .omp_outlined..1.exit: // CHECK4-NEXT: ret i32 0 @@ -5477,32 +5477,32 @@ // CHECK4-NEXT: store i32 [[TMP5]], i32* [[DOTOMP_IV]], align 4 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK4: omp.inner.for.cond: -// CHECK4-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 -// CHECK4-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !27 +// CHECK4-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 +// CHECK4-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !23 // CHECK4-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] // CHECK4-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK4: omp.inner.for.body: -// CHECK4-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK4-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK4-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP8]], 1 // CHECK4-NEXT: [[SUB:%.*]] = sub nsw i32 10, [[MUL]] -// CHECK4-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !27 -// CHECK4-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !27 -// CHECK4-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK4-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !23 +// CHECK4-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !23 +// CHECK4-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK4-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP10]], 3 // CHECK4-NEXT: [[CONV:%.*]] = sext i32 [[MUL2]] to i64 // CHECK4-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP9]], [[CONV]] -// CHECK4-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !27 -// CHECK4-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !27 +// CHECK4-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !23 +// CHECK4-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !23 // CHECK4-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK4-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !27 +// CHECK4-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !23 // CHECK4-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK4: omp.body.continue: // CHECK4-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK4: omp.inner.for.inc: -// CHECK4-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK4-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK4-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP12]], 1 -// CHECK4-NEXT: store i32 [[ADD4]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK4-NEXT: store i32 [[ADD4]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] // CHECK4: omp.inner.for.end: // CHECK4-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK4: omp.dispatch.inc: @@ -5609,44 +5609,44 @@ // CHECK4-NEXT: store i64 [[TMP6]], i64* [[DOTOMP_IV]], align 8 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK4: omp.inner.for.cond: -// CHECK4-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK4-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !30 +// CHECK4-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK4-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !26 // CHECK4-NEXT: [[CMP4:%.*]] = icmp ule i64 [[TMP7]], [[TMP8]] // CHECK4-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK4: omp.inner.for.body: -// CHECK4-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 +// CHECK4-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 // CHECK4-NEXT: [[MUL:%.*]] = mul i64 [[TMP9]], 400 // CHECK4-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK4-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !30 -// CHECK4-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !30 +// CHECK4-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !26 +// CHECK4-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !26 // CHECK4-NEXT: [[CONV5:%.*]] = sext i32 [[TMP10]] to i64 -// CHECK4-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK4-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !30 +// CHECK4-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK4-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !26 // CHECK4-NEXT: [[MUL6:%.*]] = mul i64 [[TMP11]], [[TMP12]] // CHECK4-NEXT: [[ADD:%.*]] = add i64 [[CONV5]], [[MUL6]] // CHECK4-NEXT: [[CONV7:%.*]] = trunc i64 [[ADD]] to i32 -// CHECK4-NEXT: store i32 [[CONV7]], i32* [[LIN2]], align 4, !llvm.access.group !30 -// CHECK4-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4, !llvm.access.group !30 +// CHECK4-NEXT: store i32 [[CONV7]], i32* [[LIN2]], align 4, !llvm.access.group !26 +// CHECK4-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4, !llvm.access.group !26 // CHECK4-NEXT: [[CONV8:%.*]] = sext i32 [[TMP13]] to i64 -// CHECK4-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK4-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !30 +// CHECK4-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK4-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !26 // CHECK4-NEXT: [[MUL9:%.*]] = mul i64 [[TMP14]], [[TMP15]] // CHECK4-NEXT: [[ADD10:%.*]] = add i64 [[CONV8]], [[MUL9]] // CHECK4-NEXT: [[CONV11:%.*]] = trunc i64 [[ADD10]] to i32 -// CHECK4-NEXT: store i32 [[CONV11]], i32* [[A3]], align 4, !llvm.access.group !30 -// CHECK4-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !30 +// CHECK4-NEXT: store i32 [[CONV11]], i32* [[A3]], align 4, !llvm.access.group !26 +// CHECK4-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !26 // CHECK4-NEXT: [[CONV12:%.*]] = sext i16 [[TMP16]] to i32 // CHECK4-NEXT: [[ADD13:%.*]] = add nsw i32 [[CONV12]], 1 // CHECK4-NEXT: [[CONV14:%.*]] = trunc i32 [[ADD13]] to i16 -// CHECK4-NEXT: store i16 [[CONV14]], i16* [[CONV]], align 4, !llvm.access.group !30 +// CHECK4-NEXT: store i16 [[CONV14]], i16* [[CONV]], align 4, !llvm.access.group !26 // CHECK4-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK4: omp.body.continue: // CHECK4-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK4: omp.inner.for.inc: -// CHECK4-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 +// CHECK4-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 // CHECK4-NEXT: [[ADD15:%.*]] = add i64 [[TMP17]], 1 -// CHECK4-NEXT: store i64 [[ADD15]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK4-NEXT: store i64 [[ADD15]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP27:![0-9]+]] // CHECK4: omp.inner.for.end: // CHECK4-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK4: omp.loop.exit: @@ -5743,32 +5743,32 @@ // CHECK4-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK4: omp.inner.for.cond: -// CHECK4-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 -// CHECK4-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !33 +// CHECK4-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 +// CHECK4-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !29 // CHECK4-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK4-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK4: omp.inner.for.body: -// CHECK4-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 +// CHECK4-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 // CHECK4-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 4 // CHECK4-NEXT: [[ADD:%.*]] = add nsw i32 6, [[MUL]] // CHECK4-NEXT: [[CONV2:%.*]] = trunc i32 [[ADD]] to i16 -// CHECK4-NEXT: store i16 [[CONV2]], i16* [[IT]], align 2, !llvm.access.group !33 -// CHECK4-NEXT: [[TMP8:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !33 +// CHECK4-NEXT: store i16 [[CONV2]], i16* [[IT]], align 2, !llvm.access.group !29 +// CHECK4-NEXT: [[TMP8:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !29 // CHECK4-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], 1 -// CHECK4-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !33 -// CHECK4-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !33 +// CHECK4-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !29 +// CHECK4-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !29 // CHECK4-NEXT: [[CONV4:%.*]] = sext i16 [[TMP9]] to i32 // CHECK4-NEXT: [[ADD5:%.*]] = add nsw i32 [[CONV4]], 1 // CHECK4-NEXT: [[CONV6:%.*]] = trunc i32 [[ADD5]] to i16 -// CHECK4-NEXT: store i16 [[CONV6]], i16* [[CONV]], align 4, !llvm.access.group !33 +// CHECK4-NEXT: store i16 [[CONV6]], i16* [[CONV]], align 4, !llvm.access.group !29 // CHECK4-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK4: omp.body.continue: // CHECK4-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK4: omp.inner.for.inc: -// CHECK4-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 +// CHECK4-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 // CHECK4-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK4-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK4-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] // CHECK4: omp.inner.for.end: // CHECK4-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK4: omp.loop.exit: @@ -5898,60 +5898,60 @@ // CHECK4: omp.dispatch.body: // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK4: omp.inner.for.cond: -// CHECK4-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 -// CHECK4-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK4-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]] // CHECK4-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK4: omp.inner.for.body: -// CHECK4-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1 // CHECK4-NEXT: [[SUB:%.*]] = sub nsw i32 122, [[MUL]] // CHECK4-NEXT: [[CONV:%.*]] = trunc i32 [[SUB]] to i8 -// CHECK4-NEXT: store i8 [[CONV]], i8* [[IT]], align 1, !llvm.access.group !36 -// CHECK4-NEXT: [[TMP19:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: store i8 [[CONV]], i8* [[IT]], align 1, !llvm.access.group !32 +// CHECK4-NEXT: [[TMP19:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP19]], 1 -// CHECK4-NEXT: store i32 [[ADD]], i32* [[A_ADDR]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: store i32 [[ADD]], i32* [[A_ADDR]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x float], [10 x float]* [[TMP0]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[CONV7:%.*]] = fpext float [[TMP20]] to double // CHECK4-NEXT: [[ADD8:%.*]] = fadd double [[CONV7]], 1.000000e+00 // CHECK4-NEXT: [[CONV9:%.*]] = fptrunc double [[ADD8]] to float -// CHECK4-NEXT: store float [[CONV9]], float* [[ARRAYIDX]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: store float [[CONV9]], float* [[ARRAYIDX]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, float* [[TMP2]], i32 3 -// CHECK4-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX10]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX10]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[CONV11:%.*]] = fpext float [[TMP21]] to double // CHECK4-NEXT: [[ADD12:%.*]] = fadd double [[CONV11]], 1.000000e+00 // CHECK4-NEXT: [[CONV13:%.*]] = fptrunc double [[ADD12]] to float -// CHECK4-NEXT: store float [[CONV13]], float* [[ARRAYIDX10]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: store float [[CONV13]], float* [[ARRAYIDX10]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[TMP3]], i32 0, i32 1 // CHECK4-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x double], [10 x double]* [[ARRAYIDX14]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX15]], align 8, !llvm.access.group !36 +// CHECK4-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX15]], align 8, !llvm.access.group !32 // CHECK4-NEXT: [[ADD16:%.*]] = fadd double [[TMP22]], 1.000000e+00 -// CHECK4-NEXT: store double [[ADD16]], double* [[ARRAYIDX15]], align 8, !llvm.access.group !36 +// CHECK4-NEXT: store double [[ADD16]], double* [[ARRAYIDX15]], align 8, !llvm.access.group !32 // CHECK4-NEXT: [[TMP23:%.*]] = mul nsw i32 1, [[TMP5]] // CHECK4-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds double, double* [[TMP6]], i32 [[TMP23]] // CHECK4-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX17]], i32 3 -// CHECK4-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX18]], align 8, !llvm.access.group !36 +// CHECK4-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX18]], align 8, !llvm.access.group !32 // CHECK4-NEXT: [[ADD19:%.*]] = fadd double [[TMP24]], 1.000000e+00 -// CHECK4-NEXT: store double [[ADD19]], double* [[ARRAYIDX18]], align 8, !llvm.access.group !36 +// CHECK4-NEXT: store double [[ADD19]], double* [[ARRAYIDX18]], align 8, !llvm.access.group !32 // CHECK4-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_TT:%.*]], %struct.TT* [[TMP7]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[ADD20:%.*]] = add nsw i64 [[TMP25]], 1 -// CHECK4-NEXT: store i64 [[ADD20]], i64* [[X]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: store i64 [[ADD20]], i64* [[X]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_TT]], %struct.TT* [[TMP7]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[CONV21:%.*]] = sext i8 [[TMP26]] to i32 // CHECK4-NEXT: [[ADD22:%.*]] = add nsw i32 [[CONV21]], 1 // CHECK4-NEXT: [[CONV23:%.*]] = trunc i32 [[ADD22]] to i8 -// CHECK4-NEXT: store i8 [[CONV23]], i8* [[Y]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: store i8 [[CONV23]], i8* [[Y]], align 4, !llvm.access.group !32 // CHECK4-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK4: omp.body.continue: // CHECK4-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK4: omp.inner.for.inc: -// CHECK4-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 +// CHECK4-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 // CHECK4-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP27]], 1 -// CHECK4-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK4-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] // CHECK4: omp.inner.for.end: // CHECK4-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK4: omp.dispatch.inc: @@ -6347,37 +6347,37 @@ // CHECK4-NEXT: store i64 [[TMP8]], i64* [[DOTOMP_IV]], align 8 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK4: omp.inner.for.cond: -// CHECK4-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 -// CHECK4-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !39 +// CHECK4-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 +// CHECK4-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !35 // CHECK4-NEXT: [[CMP3:%.*]] = icmp ule i64 [[TMP9]], [[TMP10]] // CHECK4-NEXT: br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK4: omp.inner.for.body: -// CHECK4-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 +// CHECK4-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 // CHECK4-NEXT: [[MUL:%.*]] = mul i64 [[TMP11]], 400 // CHECK4-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK4-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !39 -// CHECK4-NEXT: [[TMP12:%.*]] = load i32, i32* [[B_ADDR]], align 4, !llvm.access.group !39 +// CHECK4-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !35 +// CHECK4-NEXT: [[TMP12:%.*]] = load i32, i32* [[B_ADDR]], align 4, !llvm.access.group !35 // CHECK4-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP12]] to double // CHECK4-NEXT: [[ADD:%.*]] = fadd double [[CONV]], 1.500000e+00 // CHECK4-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK4-NEXT: store double [[ADD]], double* [[A]], align 4, !llvm.access.group !39 +// CHECK4-NEXT: store double [[ADD]], double* [[A]], align 4, !llvm.access.group !35 // CHECK4-NEXT: [[A4:%.*]] = getelementptr inbounds [[STRUCT_S1]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP13:%.*]] = load double, double* [[A4]], align 4, !llvm.access.group !39 +// CHECK4-NEXT: [[TMP13:%.*]] = load double, double* [[A4]], align 4, !llvm.access.group !35 // CHECK4-NEXT: [[INC:%.*]] = fadd double [[TMP13]], 1.000000e+00 -// CHECK4-NEXT: store double [[INC]], double* [[A4]], align 4, !llvm.access.group !39 +// CHECK4-NEXT: store double [[INC]], double* [[A4]], align 4, !llvm.access.group !35 // CHECK4-NEXT: [[CONV5:%.*]] = fptosi double [[INC]] to i16 // CHECK4-NEXT: [[TMP14:%.*]] = mul nsw i32 1, [[TMP2]] // CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, i16* [[TMP3]], i32 [[TMP14]] // CHECK4-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds i16, i16* [[ARRAYIDX]], i32 1 -// CHECK4-NEXT: store i16 [[CONV5]], i16* [[ARRAYIDX6]], align 2, !llvm.access.group !39 +// CHECK4-NEXT: store i16 [[CONV5]], i16* [[ARRAYIDX6]], align 2, !llvm.access.group !35 // CHECK4-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK4: omp.body.continue: // CHECK4-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK4: omp.inner.for.inc: -// CHECK4-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 +// CHECK4-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 // CHECK4-NEXT: [[ADD7:%.*]] = add i64 [[TMP15]], 1 -// CHECK4-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK4-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] // CHECK4: omp.inner.for.end: // CHECK4-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK4: omp.loop.exit: @@ -6515,35 +6515,35 @@ // CHECK4-NEXT: store i64 [[TMP5]], i64* [[DOTOMP_IV]], align 8 // CHECK4-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK4: omp.inner.for.cond: -// CHECK4-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !42 -// CHECK4-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !42 +// CHECK4-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK4-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !38 // CHECK4-NEXT: [[CMP1:%.*]] = icmp sle i64 [[TMP6]], [[TMP7]] // CHECK4-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK4: omp.inner.for.body: -// CHECK4-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !42 +// CHECK4-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 // CHECK4-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP8]], 3 // CHECK4-NEXT: [[ADD:%.*]] = add nsw i64 -10, [[MUL]] -// CHECK4-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !42 -// CHECK4-NEXT: [[TMP9:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !42 +// CHECK4-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !38 +// CHECK4-NEXT: [[TMP9:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !38 // CHECK4-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1 -// CHECK4-NEXT: store i32 [[ADD2]], i32* [[A_ADDR]], align 4, !llvm.access.group !42 -// CHECK4-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !42 +// CHECK4-NEXT: store i32 [[ADD2]], i32* [[A_ADDR]], align 4, !llvm.access.group !38 +// CHECK4-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !38 // CHECK4-NEXT: [[CONV3:%.*]] = sext i16 [[TMP10]] to i32 // CHECK4-NEXT: [[ADD4:%.*]] = add nsw i32 [[CONV3]], 1 // CHECK4-NEXT: [[CONV5:%.*]] = trunc i32 [[ADD4]] to i16 -// CHECK4-NEXT: store i16 [[CONV5]], i16* [[CONV]], align 4, !llvm.access.group !42 +// CHECK4-NEXT: store i16 [[CONV5]], i16* [[CONV]], align 4, !llvm.access.group !38 // CHECK4-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[TMP0]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !42 +// CHECK4-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !38 // CHECK4-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK4-NEXT: store i32 [[ADD6]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !42 +// CHECK4-NEXT: store i32 [[ADD6]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !38 // CHECK4-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK4: omp.body.continue: // CHECK4-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK4: omp.inner.for.inc: -// CHECK4-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !42 +// CHECK4-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 // CHECK4-NEXT: [[ADD7:%.*]] = add nsw i64 [[TMP12]], 1 -// CHECK4-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !42 -// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK4-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK4-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP39:![0-9]+]] // CHECK4: omp.inner.for.end: // CHECK4-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK4: omp.loop.exit: @@ -6956,22 +6956,22 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !25 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !25 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !25 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !25 -// CHECK5-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK5-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK5-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK5-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META21]]), !noalias !19 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !19 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !19 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !19 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !19 +// CHECK5-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK5-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !19 +// CHECK5-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK5-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK5: omp_offload.failed.i: -// CHECK5-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]] +// CHECK5-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]], !noalias !19 // CHECK5-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK5: .omp_outlined..1.exit: // CHECK5-NEXT: ret i32 0 @@ -7039,32 +7039,32 @@ // CHECK5-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK5: omp.inner.for.cond: -// CHECK5-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 -// CHECK5-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !26 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !22 // CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK5: omp.inner.for.body: -// CHECK5-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1 // CHECK5-NEXT: [[SUB:%.*]] = sub nsw i32 10, [[MUL]] -// CHECK5-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !26 -// CHECK5-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !26 -// CHECK5-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK5-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !22 +// CHECK5-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !22 +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK5-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3 // CHECK5-NEXT: [[CONV3:%.*]] = sext i32 [[MUL2]] to i64 // CHECK5-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP8]], [[CONV3]] -// CHECK5-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !26 -// CHECK5-NEXT: [[TMP10:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !26 +// CHECK5-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !22 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !22 // CHECK5-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK5-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !26 +// CHECK5-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !22 // 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: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK5-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK5-NEXT: store i32 [[ADD5]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 -// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP27:![0-9]+]] +// CHECK5-NEXT: store i32 [[ADD5]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP23:![0-9]+]] // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK5: omp.dispatch.inc: @@ -7177,44 +7177,44 @@ // CHECK5-NEXT: store i64 [[TMP6]], i64* [[DOTOMP_IV]], align 8 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK5: omp.inner.for.cond: -// CHECK5-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK5-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !29 +// CHECK5-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK5-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !25 // CHECK5-NEXT: [[CMP6:%.*]] = icmp ule i64 [[TMP7]], [[TMP8]] // CHECK5-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK5: omp.inner.for.body: -// CHECK5-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 +// CHECK5-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 // CHECK5-NEXT: [[MUL:%.*]] = mul i64 [[TMP9]], 400 // CHECK5-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK5-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !29 -// CHECK5-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !29 +// CHECK5-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !25 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !25 // CHECK5-NEXT: [[CONV7:%.*]] = sext i32 [[TMP10]] to i64 -// CHECK5-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK5-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !29 +// CHECK5-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK5-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !25 // CHECK5-NEXT: [[MUL8:%.*]] = mul i64 [[TMP11]], [[TMP12]] // CHECK5-NEXT: [[ADD:%.*]] = add i64 [[CONV7]], [[MUL8]] // CHECK5-NEXT: [[CONV9:%.*]] = trunc i64 [[ADD]] to i32 -// CHECK5-NEXT: store i32 [[CONV9]], i32* [[LIN4]], align 4, !llvm.access.group !29 -// CHECK5-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START3]], align 4, !llvm.access.group !29 +// CHECK5-NEXT: store i32 [[CONV9]], i32* [[LIN4]], align 4, !llvm.access.group !25 +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START3]], align 4, !llvm.access.group !25 // CHECK5-NEXT: [[CONV10:%.*]] = sext i32 [[TMP13]] to i64 -// CHECK5-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK5-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !29 +// CHECK5-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK5-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !25 // CHECK5-NEXT: [[MUL11:%.*]] = mul i64 [[TMP14]], [[TMP15]] // CHECK5-NEXT: [[ADD12:%.*]] = add i64 [[CONV10]], [[MUL11]] // CHECK5-NEXT: [[CONV13:%.*]] = trunc i64 [[ADD12]] to i32 -// CHECK5-NEXT: store i32 [[CONV13]], i32* [[A5]], align 4, !llvm.access.group !29 -// CHECK5-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 8, !llvm.access.group !29 +// CHECK5-NEXT: store i32 [[CONV13]], i32* [[A5]], align 4, !llvm.access.group !25 +// CHECK5-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 8, !llvm.access.group !25 // CHECK5-NEXT: [[CONV14:%.*]] = sext i16 [[TMP16]] to i32 // CHECK5-NEXT: [[ADD15:%.*]] = add nsw i32 [[CONV14]], 1 // CHECK5-NEXT: [[CONV16:%.*]] = trunc i32 [[ADD15]] to i16 -// CHECK5-NEXT: store i16 [[CONV16]], i16* [[CONV]], align 8, !llvm.access.group !29 +// CHECK5-NEXT: store i16 [[CONV16]], i16* [[CONV]], align 8, !llvm.access.group !25 // 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: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 +// CHECK5-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 // CHECK5-NEXT: [[ADD17:%.*]] = add i64 [[TMP17]], 1 -// CHECK5-NEXT: store i64 [[ADD17]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] +// CHECK5-NEXT: store i64 [[ADD17]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: @@ -7314,32 +7314,32 @@ // CHECK5-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK5: omp.inner.for.cond: -// CHECK5-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 -// CHECK5-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !32 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !28 // CHECK5-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK5-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK5: omp.inner.for.body: -// CHECK5-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 // CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 4 // CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 6, [[MUL]] // CHECK5-NEXT: [[CONV3:%.*]] = trunc i32 [[ADD]] to i16 -// CHECK5-NEXT: store i16 [[CONV3]], i16* [[IT]], align 2, !llvm.access.group !32 -// CHECK5-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !32 +// CHECK5-NEXT: store i16 [[CONV3]], i16* [[IT]], align 2, !llvm.access.group !28 +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !28 // CHECK5-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP8]], 1 -// CHECK5-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !32 -// CHECK5-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !32 +// CHECK5-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !28 +// CHECK5-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !28 // CHECK5-NEXT: [[CONV5:%.*]] = sext i16 [[TMP9]] to i32 // CHECK5-NEXT: [[ADD6:%.*]] = add nsw i32 [[CONV5]], 1 // CHECK5-NEXT: [[CONV7:%.*]] = trunc i32 [[ADD6]] to i16 -// CHECK5-NEXT: store i16 [[CONV7]], i16* [[CONV1]], align 8, !llvm.access.group !32 +// CHECK5-NEXT: store i16 [[CONV7]], i16* [[CONV1]], align 8, !llvm.access.group !28 // 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: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 // CHECK5-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK5-NEXT: store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 -// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK5-NEXT: store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: @@ -7475,60 +7475,60 @@ // CHECK5: omp.dispatch.body: // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK5: omp.inner.for.cond: -// CHECK5-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 -// CHECK5-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !35 +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !31 // CHECK5-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]] // CHECK5-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK5: omp.inner.for.body: -// CHECK5-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 +// CHECK5-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 // CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1 // CHECK5-NEXT: [[SUB:%.*]] = sub nsw i32 122, [[MUL]] // CHECK5-NEXT: [[CONV8:%.*]] = trunc i32 [[SUB]] to i8 -// CHECK5-NEXT: store i8 [[CONV8]], i8* [[IT]], align 1, !llvm.access.group !35 -// CHECK5-NEXT: [[TMP19:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: store i8 [[CONV8]], i8* [[IT]], align 1, !llvm.access.group !31 +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !31 // CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP19]], 1 -// CHECK5-NEXT: store i32 [[ADD]], i32* [[CONV]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: store i32 [[ADD]], i32* [[CONV]], align 8, !llvm.access.group !31 // CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x float], [10 x float]* [[TMP0]], i64 0, i64 2 -// CHECK5-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !35 +// CHECK5-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !31 // CHECK5-NEXT: [[CONV9:%.*]] = fpext float [[TMP20]] to double // CHECK5-NEXT: [[ADD10:%.*]] = fadd double [[CONV9]], 1.000000e+00 // CHECK5-NEXT: [[CONV11:%.*]] = fptrunc double [[ADD10]] to float -// CHECK5-NEXT: store float [[CONV11]], float* [[ARRAYIDX]], align 4, !llvm.access.group !35 +// CHECK5-NEXT: store float [[CONV11]], float* [[ARRAYIDX]], align 4, !llvm.access.group !31 // CHECK5-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds float, float* [[TMP2]], i64 3 -// CHECK5-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX12]], align 4, !llvm.access.group !35 +// CHECK5-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX12]], align 4, !llvm.access.group !31 // CHECK5-NEXT: [[CONV13:%.*]] = fpext float [[TMP21]] to double // CHECK5-NEXT: [[ADD14:%.*]] = fadd double [[CONV13]], 1.000000e+00 // CHECK5-NEXT: [[CONV15:%.*]] = fptrunc double [[ADD14]] to float -// CHECK5-NEXT: store float [[CONV15]], float* [[ARRAYIDX12]], align 4, !llvm.access.group !35 +// CHECK5-NEXT: store float [[CONV15]], float* [[ARRAYIDX12]], align 4, !llvm.access.group !31 // CHECK5-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[TMP3]], i64 0, i64 1 // CHECK5-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x double], [10 x double]* [[ARRAYIDX16]], i64 0, i64 2 -// CHECK5-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX17]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX17]], align 8, !llvm.access.group !31 // CHECK5-NEXT: [[ADD18:%.*]] = fadd double [[TMP22]], 1.000000e+00 -// CHECK5-NEXT: store double [[ADD18]], double* [[ARRAYIDX17]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: store double [[ADD18]], double* [[ARRAYIDX17]], align 8, !llvm.access.group !31 // CHECK5-NEXT: [[TMP23:%.*]] = mul nsw i64 1, [[TMP5]] // CHECK5-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds double, double* [[TMP6]], i64 [[TMP23]] // CHECK5-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX19]], i64 3 -// CHECK5-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX20]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX20]], align 8, !llvm.access.group !31 // CHECK5-NEXT: [[ADD21:%.*]] = fadd double [[TMP24]], 1.000000e+00 -// CHECK5-NEXT: store double [[ADD21]], double* [[ARRAYIDX20]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: store double [[ADD21]], double* [[ARRAYIDX20]], align 8, !llvm.access.group !31 // CHECK5-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_TT:%.*]], %struct.TT* [[TMP7]], i32 0, i32 0 -// CHECK5-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 8, !llvm.access.group !31 // CHECK5-NEXT: [[ADD22:%.*]] = add nsw i64 [[TMP25]], 1 -// CHECK5-NEXT: store i64 [[ADD22]], i64* [[X]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: store i64 [[ADD22]], i64* [[X]], align 8, !llvm.access.group !31 // CHECK5-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_TT]], %struct.TT* [[TMP7]], i32 0, i32 1 -// CHECK5-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 8, !llvm.access.group !31 // CHECK5-NEXT: [[CONV23:%.*]] = sext i8 [[TMP26]] to i32 // CHECK5-NEXT: [[ADD24:%.*]] = add nsw i32 [[CONV23]], 1 // CHECK5-NEXT: [[CONV25:%.*]] = trunc i32 [[ADD24]] to i8 -// CHECK5-NEXT: store i8 [[CONV25]], i8* [[Y]], align 8, !llvm.access.group !35 +// CHECK5-NEXT: store i8 [[CONV25]], i8* [[Y]], align 8, !llvm.access.group !31 // 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: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 +// CHECK5-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 // CHECK5-NEXT: [[ADD26:%.*]] = add nsw i32 [[TMP27]], 1 -// CHECK5-NEXT: store i32 [[ADD26]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 -// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] +// CHECK5-NEXT: store i32 [[ADD26]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP32:![0-9]+]] // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK5: omp.dispatch.inc: @@ -7988,37 +7988,37 @@ // CHECK5-NEXT: store i64 [[TMP9]], i64* [[DOTOMP_IV]], align 8 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK5: omp.inner.for.cond: -// CHECK5-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 -// CHECK5-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !38 +// CHECK5-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 +// CHECK5-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !34 // CHECK5-NEXT: [[CMP4:%.*]] = icmp ule i64 [[TMP10]], [[TMP11]] // CHECK5-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK5: omp.inner.for.body: -// CHECK5-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK5-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 // CHECK5-NEXT: [[MUL:%.*]] = mul i64 [[TMP12]], 400 // CHECK5-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK5-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !38 -// CHECK5-NEXT: [[TMP13:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !38 +// CHECK5-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !34 +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !34 // CHECK5-NEXT: [[CONV5:%.*]] = sitofp i32 [[TMP13]] to double // CHECK5-NEXT: [[ADD:%.*]] = fadd double [[CONV5]], 1.500000e+00 // CHECK5-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK5-NEXT: store double [[ADD]], double* [[A]], align 8, !nontemporal !39, !llvm.access.group !38 +// CHECK5-NEXT: store double [[ADD]], double* [[A]], align 8, !nontemporal !35, !llvm.access.group !34 // CHECK5-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S1]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK5-NEXT: [[TMP14:%.*]] = load double, double* [[A6]], align 8, !nontemporal !39, !llvm.access.group !38 +// CHECK5-NEXT: [[TMP14:%.*]] = load double, double* [[A6]], align 8, !nontemporal !35, !llvm.access.group !34 // CHECK5-NEXT: [[INC:%.*]] = fadd double [[TMP14]], 1.000000e+00 -// CHECK5-NEXT: store double [[INC]], double* [[A6]], align 8, !nontemporal !39, !llvm.access.group !38 +// CHECK5-NEXT: store double [[INC]], double* [[A6]], align 8, !nontemporal !35, !llvm.access.group !34 // CHECK5-NEXT: [[CONV7:%.*]] = fptosi double [[INC]] to i16 // CHECK5-NEXT: [[TMP15:%.*]] = mul nsw i64 1, [[TMP2]] // CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, i16* [[TMP3]], i64 [[TMP15]] // CHECK5-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i16, i16* [[ARRAYIDX]], i64 1 -// CHECK5-NEXT: store i16 [[CONV7]], i16* [[ARRAYIDX8]], align 2, !llvm.access.group !38 +// CHECK5-NEXT: store i16 [[CONV7]], i16* [[ARRAYIDX8]], align 2, !llvm.access.group !34 // 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: [[TMP16:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK5-NEXT: [[TMP16:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 // CHECK5-NEXT: [[ADD9:%.*]] = add i64 [[TMP16]], 1 -// CHECK5-NEXT: store i64 [[ADD9]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 -// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK5-NEXT: store i64 [[ADD9]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_IF_END:%.*]] // CHECK5: omp_if.else: @@ -8070,7 +8070,7 @@ // CHECK5-NEXT: [[TMP28:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8 // CHECK5-NEXT: [[ADD30:%.*]] = add i64 [[TMP28]], 1 // CHECK5-NEXT: store i64 [[ADD30]], i64* [[DOTOMP_IV]], align 8 -// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND15]], !llvm.loop [[LOOP42:![0-9]+]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND15]], !llvm.loop [[LOOP38:![0-9]+]] // CHECK5: omp.inner.for.end31: // CHECK5-NEXT: br label [[OMP_IF_END]] // CHECK5: omp_if.end: @@ -8218,35 +8218,35 @@ // CHECK5-NEXT: store i64 [[TMP5]], i64* [[DOTOMP_IV]], align 8 // CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK5: omp.inner.for.cond: -// CHECK5-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !44 -// CHECK5-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !44 +// CHECK5-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !40 +// CHECK5-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !40 // CHECK5-NEXT: [[CMP2:%.*]] = icmp sle i64 [[TMP6]], [[TMP7]] // CHECK5-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK5: omp.inner.for.body: -// CHECK5-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !44 +// CHECK5-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !40 // CHECK5-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP8]], 3 // CHECK5-NEXT: [[ADD:%.*]] = add nsw i64 -10, [[MUL]] -// CHECK5-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !44 -// CHECK5-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !44 +// CHECK5-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !40 +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !40 // CHECK5-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP9]], 1 -// CHECK5-NEXT: store i32 [[ADD3]], i32* [[CONV]], align 8, !llvm.access.group !44 -// CHECK5-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !44 +// CHECK5-NEXT: store i32 [[ADD3]], i32* [[CONV]], align 8, !llvm.access.group !40 +// CHECK5-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !40 // CHECK5-NEXT: [[CONV4:%.*]] = sext i16 [[TMP10]] to i32 // CHECK5-NEXT: [[ADD5:%.*]] = add nsw i32 [[CONV4]], 1 // CHECK5-NEXT: [[CONV6:%.*]] = trunc i32 [[ADD5]] to i16 -// CHECK5-NEXT: store i16 [[CONV6]], i16* [[CONV1]], align 8, !llvm.access.group !44 +// CHECK5-NEXT: store i16 [[CONV6]], i16* [[CONV1]], align 8, !llvm.access.group !40 // CHECK5-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[TMP0]], i64 0, i64 2 -// CHECK5-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !44 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !40 // CHECK5-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK5-NEXT: store i32 [[ADD7]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !44 +// CHECK5-NEXT: store i32 [[ADD7]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !40 // 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: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !44 +// CHECK5-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !40 // CHECK5-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP12]], 1 -// CHECK5-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !44 -// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP45:![0-9]+]] +// CHECK5-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !40 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP41:![0-9]+]] // CHECK5: omp.inner.for.end: // CHECK5-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK5: omp.loop.exit: @@ -8659,22 +8659,22 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !25 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !25 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !25 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !25 -// CHECK6-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !25 -// CHECK6-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK6-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK6-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META21]]), !noalias !19 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !19 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !19 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !19 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !19 +// CHECK6-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !19 +// CHECK6-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !19 +// CHECK6-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK6-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK6: omp_offload.failed.i: -// CHECK6-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]] +// CHECK6-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]], !noalias !19 // CHECK6-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK6: .omp_outlined..1.exit: // CHECK6-NEXT: ret i32 0 @@ -8742,32 +8742,32 @@ // CHECK6-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK6: omp.inner.for.cond: -// CHECK6-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 -// CHECK6-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !26 +// CHECK6-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 +// CHECK6-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !22 // CHECK6-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK6-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK6: omp.inner.for.body: -// CHECK6-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK6-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK6-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1 // CHECK6-NEXT: [[SUB:%.*]] = sub nsw i32 10, [[MUL]] -// CHECK6-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !26 -// CHECK6-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !26 -// CHECK6-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK6-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !22 +// CHECK6-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !22 +// CHECK6-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK6-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP9]], 3 // CHECK6-NEXT: [[CONV3:%.*]] = sext i32 [[MUL2]] to i64 // CHECK6-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP8]], [[CONV3]] -// CHECK6-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !26 -// CHECK6-NEXT: [[TMP10:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !26 +// CHECK6-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !22 +// CHECK6-NEXT: [[TMP10:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !22 // CHECK6-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK6-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !26 +// CHECK6-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !22 // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: // CHECK6-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK6: omp.inner.for.inc: -// CHECK6-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 +// CHECK6-NEXT: [[TMP11:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 // CHECK6-NEXT: [[ADD5:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK6-NEXT: store i32 [[ADD5]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !26 -// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP27:![0-9]+]] +// CHECK6-NEXT: store i32 [[ADD5]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !22 +// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP23:![0-9]+]] // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK6: omp.dispatch.inc: @@ -8880,44 +8880,44 @@ // CHECK6-NEXT: store i64 [[TMP6]], i64* [[DOTOMP_IV]], align 8 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK6: omp.inner.for.cond: -// CHECK6-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK6-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !29 +// CHECK6-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK6-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !25 // CHECK6-NEXT: [[CMP6:%.*]] = icmp ule i64 [[TMP7]], [[TMP8]] // CHECK6-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK6: omp.inner.for.body: -// CHECK6-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 +// CHECK6-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 // CHECK6-NEXT: [[MUL:%.*]] = mul i64 [[TMP9]], 400 // CHECK6-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK6-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !29 -// CHECK6-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !29 +// CHECK6-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !25 +// CHECK6-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !25 // CHECK6-NEXT: [[CONV7:%.*]] = sext i32 [[TMP10]] to i64 -// CHECK6-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK6-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !29 +// CHECK6-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK6-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !25 // CHECK6-NEXT: [[MUL8:%.*]] = mul i64 [[TMP11]], [[TMP12]] // CHECK6-NEXT: [[ADD:%.*]] = add i64 [[CONV7]], [[MUL8]] // CHECK6-NEXT: [[CONV9:%.*]] = trunc i64 [[ADD]] to i32 -// CHECK6-NEXT: store i32 [[CONV9]], i32* [[LIN4]], align 4, !llvm.access.group !29 -// CHECK6-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START3]], align 4, !llvm.access.group !29 +// CHECK6-NEXT: store i32 [[CONV9]], i32* [[LIN4]], align 4, !llvm.access.group !25 +// CHECK6-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START3]], align 4, !llvm.access.group !25 // CHECK6-NEXT: [[CONV10:%.*]] = sext i32 [[TMP13]] to i64 -// CHECK6-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK6-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !29 +// CHECK6-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK6-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !25 // CHECK6-NEXT: [[MUL11:%.*]] = mul i64 [[TMP14]], [[TMP15]] // CHECK6-NEXT: [[ADD12:%.*]] = add i64 [[CONV10]], [[MUL11]] // CHECK6-NEXT: [[CONV13:%.*]] = trunc i64 [[ADD12]] to i32 -// CHECK6-NEXT: store i32 [[CONV13]], i32* [[A5]], align 4, !llvm.access.group !29 -// CHECK6-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 8, !llvm.access.group !29 +// CHECK6-NEXT: store i32 [[CONV13]], i32* [[A5]], align 4, !llvm.access.group !25 +// CHECK6-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 8, !llvm.access.group !25 // CHECK6-NEXT: [[CONV14:%.*]] = sext i16 [[TMP16]] to i32 // CHECK6-NEXT: [[ADD15:%.*]] = add nsw i32 [[CONV14]], 1 // CHECK6-NEXT: [[CONV16:%.*]] = trunc i32 [[ADD15]] to i16 -// CHECK6-NEXT: store i16 [[CONV16]], i16* [[CONV]], align 8, !llvm.access.group !29 +// CHECK6-NEXT: store i16 [[CONV16]], i16* [[CONV]], align 8, !llvm.access.group !25 // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: // CHECK6-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK6: omp.inner.for.inc: -// CHECK6-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 +// CHECK6-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 // CHECK6-NEXT: [[ADD17:%.*]] = add i64 [[TMP17]], 1 -// CHECK6-NEXT: store i64 [[ADD17]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !29 -// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] +// CHECK6-NEXT: store i64 [[ADD17]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !25 +// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK6: omp.loop.exit: @@ -9017,32 +9017,32 @@ // CHECK6-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK6: omp.inner.for.cond: -// CHECK6-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 -// CHECK6-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !32 +// CHECK6-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 +// CHECK6-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !28 // CHECK6-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK6-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK6: omp.inner.for.body: -// CHECK6-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK6-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 // CHECK6-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 4 // CHECK6-NEXT: [[ADD:%.*]] = add nsw i32 6, [[MUL]] // CHECK6-NEXT: [[CONV3:%.*]] = trunc i32 [[ADD]] to i16 -// CHECK6-NEXT: store i16 [[CONV3]], i16* [[IT]], align 2, !llvm.access.group !32 -// CHECK6-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !32 +// CHECK6-NEXT: store i16 [[CONV3]], i16* [[IT]], align 2, !llvm.access.group !28 +// CHECK6-NEXT: [[TMP8:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !28 // CHECK6-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP8]], 1 -// CHECK6-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !32 -// CHECK6-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !32 +// CHECK6-NEXT: store i32 [[ADD4]], i32* [[CONV]], align 8, !llvm.access.group !28 +// CHECK6-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !28 // CHECK6-NEXT: [[CONV5:%.*]] = sext i16 [[TMP9]] to i32 // CHECK6-NEXT: [[ADD6:%.*]] = add nsw i32 [[CONV5]], 1 // CHECK6-NEXT: [[CONV7:%.*]] = trunc i32 [[ADD6]] to i16 -// CHECK6-NEXT: store i16 [[CONV7]], i16* [[CONV1]], align 8, !llvm.access.group !32 +// CHECK6-NEXT: store i16 [[CONV7]], i16* [[CONV1]], align 8, !llvm.access.group !28 // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: // CHECK6-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK6: omp.inner.for.inc: -// CHECK6-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK6-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 // CHECK6-NEXT: [[ADD8:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK6-NEXT: store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 -// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK6-NEXT: store i32 [[ADD8]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !28 +// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK6: omp.loop.exit: @@ -9178,60 +9178,60 @@ // CHECK6: omp.dispatch.body: // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK6: omp.inner.for.cond: -// CHECK6-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 -// CHECK6-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !35 +// CHECK6-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 +// CHECK6-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !31 // CHECK6-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]] // CHECK6-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK6: omp.inner.for.body: -// CHECK6-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 +// CHECK6-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 // CHECK6-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1 // CHECK6-NEXT: [[SUB:%.*]] = sub nsw i32 122, [[MUL]] // CHECK6-NEXT: [[CONV8:%.*]] = trunc i32 [[SUB]] to i8 -// CHECK6-NEXT: store i8 [[CONV8]], i8* [[IT]], align 1, !llvm.access.group !35 -// CHECK6-NEXT: [[TMP19:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: store i8 [[CONV8]], i8* [[IT]], align 1, !llvm.access.group !31 +// CHECK6-NEXT: [[TMP19:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !31 // CHECK6-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP19]], 1 -// CHECK6-NEXT: store i32 [[ADD]], i32* [[CONV]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: store i32 [[ADD]], i32* [[CONV]], align 8, !llvm.access.group !31 // CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x float], [10 x float]* [[TMP0]], i64 0, i64 2 -// CHECK6-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !35 +// CHECK6-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !31 // CHECK6-NEXT: [[CONV9:%.*]] = fpext float [[TMP20]] to double // CHECK6-NEXT: [[ADD10:%.*]] = fadd double [[CONV9]], 1.000000e+00 // CHECK6-NEXT: [[CONV11:%.*]] = fptrunc double [[ADD10]] to float -// CHECK6-NEXT: store float [[CONV11]], float* [[ARRAYIDX]], align 4, !llvm.access.group !35 +// CHECK6-NEXT: store float [[CONV11]], float* [[ARRAYIDX]], align 4, !llvm.access.group !31 // CHECK6-NEXT: [[ARRAYIDX12:%.*]] = getelementptr inbounds float, float* [[TMP2]], i64 3 -// CHECK6-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX12]], align 4, !llvm.access.group !35 +// CHECK6-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX12]], align 4, !llvm.access.group !31 // CHECK6-NEXT: [[CONV13:%.*]] = fpext float [[TMP21]] to double // CHECK6-NEXT: [[ADD14:%.*]] = fadd double [[CONV13]], 1.000000e+00 // CHECK6-NEXT: [[CONV15:%.*]] = fptrunc double [[ADD14]] to float -// CHECK6-NEXT: store float [[CONV15]], float* [[ARRAYIDX12]], align 4, !llvm.access.group !35 +// CHECK6-NEXT: store float [[CONV15]], float* [[ARRAYIDX12]], align 4, !llvm.access.group !31 // CHECK6-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[TMP3]], i64 0, i64 1 // CHECK6-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [10 x double], [10 x double]* [[ARRAYIDX16]], i64 0, i64 2 -// CHECK6-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX17]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX17]], align 8, !llvm.access.group !31 // CHECK6-NEXT: [[ADD18:%.*]] = fadd double [[TMP22]], 1.000000e+00 -// CHECK6-NEXT: store double [[ADD18]], double* [[ARRAYIDX17]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: store double [[ADD18]], double* [[ARRAYIDX17]], align 8, !llvm.access.group !31 // CHECK6-NEXT: [[TMP23:%.*]] = mul nsw i64 1, [[TMP5]] // CHECK6-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds double, double* [[TMP6]], i64 [[TMP23]] // CHECK6-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX19]], i64 3 -// CHECK6-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX20]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX20]], align 8, !llvm.access.group !31 // CHECK6-NEXT: [[ADD21:%.*]] = fadd double [[TMP24]], 1.000000e+00 -// CHECK6-NEXT: store double [[ADD21]], double* [[ARRAYIDX20]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: store double [[ADD21]], double* [[ARRAYIDX20]], align 8, !llvm.access.group !31 // CHECK6-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_TT:%.*]], %struct.TT* [[TMP7]], i32 0, i32 0 -// CHECK6-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 8, !llvm.access.group !31 // CHECK6-NEXT: [[ADD22:%.*]] = add nsw i64 [[TMP25]], 1 -// CHECK6-NEXT: store i64 [[ADD22]], i64* [[X]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: store i64 [[ADD22]], i64* [[X]], align 8, !llvm.access.group !31 // CHECK6-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_TT]], %struct.TT* [[TMP7]], i32 0, i32 1 -// CHECK6-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 8, !llvm.access.group !31 // CHECK6-NEXT: [[CONV23:%.*]] = sext i8 [[TMP26]] to i32 // CHECK6-NEXT: [[ADD24:%.*]] = add nsw i32 [[CONV23]], 1 // CHECK6-NEXT: [[CONV25:%.*]] = trunc i32 [[ADD24]] to i8 -// CHECK6-NEXT: store i8 [[CONV25]], i8* [[Y]], align 8, !llvm.access.group !35 +// CHECK6-NEXT: store i8 [[CONV25]], i8* [[Y]], align 8, !llvm.access.group !31 // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: // CHECK6-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK6: omp.inner.for.inc: -// CHECK6-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 +// CHECK6-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 // CHECK6-NEXT: [[ADD26:%.*]] = add nsw i32 [[TMP27]], 1 -// CHECK6-NEXT: store i32 [[ADD26]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !35 -// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] +// CHECK6-NEXT: store i32 [[ADD26]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !31 +// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP32:![0-9]+]] // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK6: omp.dispatch.inc: @@ -9691,37 +9691,37 @@ // CHECK6-NEXT: store i64 [[TMP9]], i64* [[DOTOMP_IV]], align 8 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK6: omp.inner.for.cond: -// CHECK6-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 -// CHECK6-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !38 +// CHECK6-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 +// CHECK6-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !34 // CHECK6-NEXT: [[CMP4:%.*]] = icmp ule i64 [[TMP10]], [[TMP11]] // CHECK6-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK6: omp.inner.for.body: -// CHECK6-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK6-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 // CHECK6-NEXT: [[MUL:%.*]] = mul i64 [[TMP12]], 400 // CHECK6-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK6-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !38 -// CHECK6-NEXT: [[TMP13:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !38 +// CHECK6-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !34 +// CHECK6-NEXT: [[TMP13:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !34 // CHECK6-NEXT: [[CONV5:%.*]] = sitofp i32 [[TMP13]] to double // CHECK6-NEXT: [[ADD:%.*]] = fadd double [[CONV5]], 1.500000e+00 // CHECK6-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK6-NEXT: store double [[ADD]], double* [[A]], align 8, !nontemporal !39, !llvm.access.group !38 +// CHECK6-NEXT: store double [[ADD]], double* [[A]], align 8, !nontemporal !35, !llvm.access.group !34 // CHECK6-NEXT: [[A6:%.*]] = getelementptr inbounds [[STRUCT_S1]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK6-NEXT: [[TMP14:%.*]] = load double, double* [[A6]], align 8, !nontemporal !39, !llvm.access.group !38 +// CHECK6-NEXT: [[TMP14:%.*]] = load double, double* [[A6]], align 8, !nontemporal !35, !llvm.access.group !34 // CHECK6-NEXT: [[INC:%.*]] = fadd double [[TMP14]], 1.000000e+00 -// CHECK6-NEXT: store double [[INC]], double* [[A6]], align 8, !nontemporal !39, !llvm.access.group !38 +// CHECK6-NEXT: store double [[INC]], double* [[A6]], align 8, !nontemporal !35, !llvm.access.group !34 // CHECK6-NEXT: [[CONV7:%.*]] = fptosi double [[INC]] to i16 // CHECK6-NEXT: [[TMP15:%.*]] = mul nsw i64 1, [[TMP2]] // CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, i16* [[TMP3]], i64 [[TMP15]] // CHECK6-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds i16, i16* [[ARRAYIDX]], i64 1 -// CHECK6-NEXT: store i16 [[CONV7]], i16* [[ARRAYIDX8]], align 2, !llvm.access.group !38 +// CHECK6-NEXT: store i16 [[CONV7]], i16* [[ARRAYIDX8]], align 2, !llvm.access.group !34 // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: // CHECK6-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK6: omp.inner.for.inc: -// CHECK6-NEXT: [[TMP16:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 +// CHECK6-NEXT: [[TMP16:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 // CHECK6-NEXT: [[ADD9:%.*]] = add i64 [[TMP16]], 1 -// CHECK6-NEXT: store i64 [[ADD9]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !38 -// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK6-NEXT: store i64 [[ADD9]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !34 +// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_IF_END:%.*]] // CHECK6: omp_if.else: @@ -9773,7 +9773,7 @@ // CHECK6-NEXT: [[TMP28:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8 // CHECK6-NEXT: [[ADD30:%.*]] = add i64 [[TMP28]], 1 // CHECK6-NEXT: store i64 [[ADD30]], i64* [[DOTOMP_IV]], align 8 -// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND15]], !llvm.loop [[LOOP42:![0-9]+]] +// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND15]], !llvm.loop [[LOOP38:![0-9]+]] // CHECK6: omp.inner.for.end31: // CHECK6-NEXT: br label [[OMP_IF_END]] // CHECK6: omp_if.end: @@ -9921,35 +9921,35 @@ // CHECK6-NEXT: store i64 [[TMP5]], i64* [[DOTOMP_IV]], align 8 // CHECK6-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK6: omp.inner.for.cond: -// CHECK6-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !44 -// CHECK6-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !44 +// CHECK6-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !40 +// CHECK6-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !40 // CHECK6-NEXT: [[CMP2:%.*]] = icmp sle i64 [[TMP6]], [[TMP7]] // CHECK6-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK6: omp.inner.for.body: -// CHECK6-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !44 +// CHECK6-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !40 // CHECK6-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP8]], 3 // CHECK6-NEXT: [[ADD:%.*]] = add nsw i64 -10, [[MUL]] -// CHECK6-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !44 -// CHECK6-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !44 +// CHECK6-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !40 +// CHECK6-NEXT: [[TMP9:%.*]] = load i32, i32* [[CONV]], align 8, !llvm.access.group !40 // CHECK6-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP9]], 1 -// CHECK6-NEXT: store i32 [[ADD3]], i32* [[CONV]], align 8, !llvm.access.group !44 -// CHECK6-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !44 +// CHECK6-NEXT: store i32 [[ADD3]], i32* [[CONV]], align 8, !llvm.access.group !40 +// CHECK6-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV1]], align 8, !llvm.access.group !40 // CHECK6-NEXT: [[CONV4:%.*]] = sext i16 [[TMP10]] to i32 // CHECK6-NEXT: [[ADD5:%.*]] = add nsw i32 [[CONV4]], 1 // CHECK6-NEXT: [[CONV6:%.*]] = trunc i32 [[ADD5]] to i16 -// CHECK6-NEXT: store i16 [[CONV6]], i16* [[CONV1]], align 8, !llvm.access.group !44 +// CHECK6-NEXT: store i16 [[CONV6]], i16* [[CONV1]], align 8, !llvm.access.group !40 // CHECK6-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[TMP0]], i64 0, i64 2 -// CHECK6-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !44 +// CHECK6-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !40 // CHECK6-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK6-NEXT: store i32 [[ADD7]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !44 +// CHECK6-NEXT: store i32 [[ADD7]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !40 // CHECK6-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK6: omp.body.continue: // CHECK6-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK6: omp.inner.for.inc: -// CHECK6-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !44 +// CHECK6-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !40 // CHECK6-NEXT: [[ADD8:%.*]] = add nsw i64 [[TMP12]], 1 -// CHECK6-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !44 -// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP45:![0-9]+]] +// CHECK6-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !40 +// CHECK6-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP41:![0-9]+]] // CHECK6: omp.inner.for.end: // CHECK6-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK6: omp.loop.exit: @@ -10352,22 +10352,22 @@ // CHECK7-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 4 // CHECK7-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK7-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK7-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 -// CHECK7-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !26 -// CHECK7-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !26 -// CHECK7-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !26 -// CHECK7-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !26 -// CHECK7-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK7-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK7-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK7-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK7-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK7-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK7-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK7-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK7-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META22]]), !noalias !20 +// CHECK7-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK7-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !20 +// CHECK7-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !20 +// CHECK7-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !20 +// CHECK7-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !20 +// CHECK7-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !20 +// CHECK7-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !20 +// CHECK7-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !20 +// CHECK7-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK7-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK7: omp_offload.failed.i: -// CHECK7-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]] +// CHECK7-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]], !noalias !20 // CHECK7-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK7: .omp_outlined..1.exit: // CHECK7-NEXT: ret i32 0 @@ -10430,32 +10430,32 @@ // CHECK7-NEXT: store i32 [[TMP5]], i32* [[DOTOMP_IV]], align 4 // CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK7: omp.inner.for.cond: -// CHECK7-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 -// CHECK7-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !27 +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !23 // CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] // CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK7: omp.inner.for.body: -// CHECK7-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP8]], 1 // CHECK7-NEXT: [[SUB:%.*]] = sub nsw i32 10, [[MUL]] -// CHECK7-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !27 -// CHECK7-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !27 -// CHECK7-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK7-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !23 +// CHECK7-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !23 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK7-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP10]], 3 // CHECK7-NEXT: [[CONV:%.*]] = sext i32 [[MUL2]] to i64 // CHECK7-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP9]], [[CONV]] -// CHECK7-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !27 -// CHECK7-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !27 +// CHECK7-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !23 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !23 // CHECK7-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK7-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !27 +// CHECK7-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !23 // 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: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK7-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK7-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP12]], 1 -// CHECK7-NEXT: store i32 [[ADD4]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 -// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK7-NEXT: store i32 [[ADD4]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK7: omp.dispatch.inc: @@ -10562,44 +10562,44 @@ // CHECK7-NEXT: store i64 [[TMP6]], i64* [[DOTOMP_IV]], align 8 // CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK7: omp.inner.for.cond: -// CHECK7-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK7-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !30 +// CHECK7-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK7-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !26 // CHECK7-NEXT: [[CMP4:%.*]] = icmp ule i64 [[TMP7]], [[TMP8]] // CHECK7-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK7: omp.inner.for.body: -// CHECK7-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 +// CHECK7-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 // CHECK7-NEXT: [[MUL:%.*]] = mul i64 [[TMP9]], 400 // CHECK7-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK7-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !30 -// CHECK7-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !30 +// CHECK7-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !26 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !26 // CHECK7-NEXT: [[CONV5:%.*]] = sext i32 [[TMP10]] to i64 -// CHECK7-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK7-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !30 +// CHECK7-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK7-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !26 // CHECK7-NEXT: [[MUL6:%.*]] = mul i64 [[TMP11]], [[TMP12]] // CHECK7-NEXT: [[ADD:%.*]] = add i64 [[CONV5]], [[MUL6]] // CHECK7-NEXT: [[CONV7:%.*]] = trunc i64 [[ADD]] to i32 -// CHECK7-NEXT: store i32 [[CONV7]], i32* [[LIN2]], align 4, !llvm.access.group !30 -// CHECK7-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4, !llvm.access.group !30 +// CHECK7-NEXT: store i32 [[CONV7]], i32* [[LIN2]], align 4, !llvm.access.group !26 +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4, !llvm.access.group !26 // CHECK7-NEXT: [[CONV8:%.*]] = sext i32 [[TMP13]] to i64 -// CHECK7-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK7-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !30 +// CHECK7-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK7-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !26 // CHECK7-NEXT: [[MUL9:%.*]] = mul i64 [[TMP14]], [[TMP15]] // CHECK7-NEXT: [[ADD10:%.*]] = add i64 [[CONV8]], [[MUL9]] // CHECK7-NEXT: [[CONV11:%.*]] = trunc i64 [[ADD10]] to i32 -// CHECK7-NEXT: store i32 [[CONV11]], i32* [[A3]], align 4, !llvm.access.group !30 -// CHECK7-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !30 +// CHECK7-NEXT: store i32 [[CONV11]], i32* [[A3]], align 4, !llvm.access.group !26 +// CHECK7-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !26 // CHECK7-NEXT: [[CONV12:%.*]] = sext i16 [[TMP16]] to i32 // CHECK7-NEXT: [[ADD13:%.*]] = add nsw i32 [[CONV12]], 1 // CHECK7-NEXT: [[CONV14:%.*]] = trunc i32 [[ADD13]] to i16 -// CHECK7-NEXT: store i16 [[CONV14]], i16* [[CONV]], align 4, !llvm.access.group !30 +// CHECK7-NEXT: store i16 [[CONV14]], i16* [[CONV]], align 4, !llvm.access.group !26 // 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: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 +// CHECK7-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 // CHECK7-NEXT: [[ADD15:%.*]] = add i64 [[TMP17]], 1 -// CHECK7-NEXT: store i64 [[ADD15]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK7-NEXT: store i64 [[ADD15]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP27:![0-9]+]] // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK7: omp.loop.exit: @@ -10696,32 +10696,32 @@ // CHECK7-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK7: omp.inner.for.cond: -// CHECK7-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 -// CHECK7-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !33 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !29 // CHECK7-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK7-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK7: omp.inner.for.body: -// CHECK7-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 // CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 4 // CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 6, [[MUL]] // CHECK7-NEXT: [[CONV2:%.*]] = trunc i32 [[ADD]] to i16 -// CHECK7-NEXT: store i16 [[CONV2]], i16* [[IT]], align 2, !llvm.access.group !33 -// CHECK7-NEXT: [[TMP8:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !33 +// CHECK7-NEXT: store i16 [[CONV2]], i16* [[IT]], align 2, !llvm.access.group !29 +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !29 // CHECK7-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], 1 -// CHECK7-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !33 -// CHECK7-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !33 +// CHECK7-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !29 +// CHECK7-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !29 // CHECK7-NEXT: [[CONV4:%.*]] = sext i16 [[TMP9]] to i32 // CHECK7-NEXT: [[ADD5:%.*]] = add nsw i32 [[CONV4]], 1 // CHECK7-NEXT: [[CONV6:%.*]] = trunc i32 [[ADD5]] to i16 -// CHECK7-NEXT: store i16 [[CONV6]], i16* [[CONV]], align 4, !llvm.access.group !33 +// CHECK7-NEXT: store i16 [[CONV6]], i16* [[CONV]], align 4, !llvm.access.group !29 // 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: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 // CHECK7-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK7-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 -// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK7-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK7: omp.loop.exit: @@ -10851,60 +10851,60 @@ // CHECK7: omp.dispatch.body: // CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK7: omp.inner.for.cond: -// CHECK7-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 -// CHECK7-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK7-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]] // CHECK7-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK7: omp.inner.for.body: -// CHECK7-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1 // CHECK7-NEXT: [[SUB:%.*]] = sub nsw i32 122, [[MUL]] // CHECK7-NEXT: [[CONV:%.*]] = trunc i32 [[SUB]] to i8 -// CHECK7-NEXT: store i8 [[CONV]], i8* [[IT]], align 1, !llvm.access.group !36 -// CHECK7-NEXT: [[TMP19:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: store i8 [[CONV]], i8* [[IT]], align 1, !llvm.access.group !32 +// CHECK7-NEXT: [[TMP19:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP19]], 1 -// CHECK7-NEXT: store i32 [[ADD]], i32* [[A_ADDR]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: store i32 [[ADD]], i32* [[A_ADDR]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x float], [10 x float]* [[TMP0]], i32 0, i32 2 -// CHECK7-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[CONV7:%.*]] = fpext float [[TMP20]] to double // CHECK7-NEXT: [[ADD8:%.*]] = fadd double [[CONV7]], 1.000000e+00 // CHECK7-NEXT: [[CONV9:%.*]] = fptrunc double [[ADD8]] to float -// CHECK7-NEXT: store float [[CONV9]], float* [[ARRAYIDX]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: store float [[CONV9]], float* [[ARRAYIDX]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, float* [[TMP2]], i32 3 -// CHECK7-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX10]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX10]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[CONV11:%.*]] = fpext float [[TMP21]] to double // CHECK7-NEXT: [[ADD12:%.*]] = fadd double [[CONV11]], 1.000000e+00 // CHECK7-NEXT: [[CONV13:%.*]] = fptrunc double [[ADD12]] to float -// CHECK7-NEXT: store float [[CONV13]], float* [[ARRAYIDX10]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: store float [[CONV13]], float* [[ARRAYIDX10]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[TMP3]], i32 0, i32 1 // CHECK7-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x double], [10 x double]* [[ARRAYIDX14]], i32 0, i32 2 -// CHECK7-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX15]], align 8, !llvm.access.group !36 +// CHECK7-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX15]], align 8, !llvm.access.group !32 // CHECK7-NEXT: [[ADD16:%.*]] = fadd double [[TMP22]], 1.000000e+00 -// CHECK7-NEXT: store double [[ADD16]], double* [[ARRAYIDX15]], align 8, !llvm.access.group !36 +// CHECK7-NEXT: store double [[ADD16]], double* [[ARRAYIDX15]], align 8, !llvm.access.group !32 // CHECK7-NEXT: [[TMP23:%.*]] = mul nsw i32 1, [[TMP5]] // CHECK7-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds double, double* [[TMP6]], i32 [[TMP23]] // CHECK7-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX17]], i32 3 -// CHECK7-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX18]], align 8, !llvm.access.group !36 +// CHECK7-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX18]], align 8, !llvm.access.group !32 // CHECK7-NEXT: [[ADD19:%.*]] = fadd double [[TMP24]], 1.000000e+00 -// CHECK7-NEXT: store double [[ADD19]], double* [[ARRAYIDX18]], align 8, !llvm.access.group !36 +// CHECK7-NEXT: store double [[ADD19]], double* [[ARRAYIDX18]], align 8, !llvm.access.group !32 // CHECK7-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_TT:%.*]], %struct.TT* [[TMP7]], i32 0, i32 0 -// CHECK7-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[ADD20:%.*]] = add nsw i64 [[TMP25]], 1 -// CHECK7-NEXT: store i64 [[ADD20]], i64* [[X]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: store i64 [[ADD20]], i64* [[X]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_TT]], %struct.TT* [[TMP7]], i32 0, i32 1 -// CHECK7-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[CONV21:%.*]] = sext i8 [[TMP26]] to i32 // CHECK7-NEXT: [[ADD22:%.*]] = add nsw i32 [[CONV21]], 1 // CHECK7-NEXT: [[CONV23:%.*]] = trunc i32 [[ADD22]] to i8 -// CHECK7-NEXT: store i8 [[CONV23]], i8* [[Y]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: store i8 [[CONV23]], i8* [[Y]], align 4, !llvm.access.group !32 // 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: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 +// CHECK7-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 // CHECK7-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP27]], 1 -// CHECK7-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 -// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK7-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK7: omp.dispatch.inc: @@ -11358,37 +11358,37 @@ // CHECK7-NEXT: store i64 [[TMP9]], i64* [[DOTOMP_IV]], align 8 // CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK7: omp.inner.for.cond: -// CHECK7-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 -// CHECK7-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !39 +// CHECK7-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 +// CHECK7-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !35 // CHECK7-NEXT: [[CMP3:%.*]] = icmp ule i64 [[TMP10]], [[TMP11]] // CHECK7-NEXT: br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK7: omp.inner.for.body: -// CHECK7-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 +// CHECK7-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 // CHECK7-NEXT: [[MUL:%.*]] = mul i64 [[TMP12]], 400 // CHECK7-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK7-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !39 -// CHECK7-NEXT: [[TMP13:%.*]] = load i32, i32* [[B_ADDR]], align 4, !llvm.access.group !39 +// CHECK7-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !35 +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, i32* [[B_ADDR]], align 4, !llvm.access.group !35 // CHECK7-NEXT: [[CONV4:%.*]] = sitofp i32 [[TMP13]] to double // CHECK7-NEXT: [[ADD:%.*]] = fadd double [[CONV4]], 1.500000e+00 // CHECK7-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK7-NEXT: store double [[ADD]], double* [[A]], align 4, !nontemporal !40, !llvm.access.group !39 +// CHECK7-NEXT: store double [[ADD]], double* [[A]], align 4, !nontemporal !36, !llvm.access.group !35 // CHECK7-NEXT: [[A5:%.*]] = getelementptr inbounds [[STRUCT_S1]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK7-NEXT: [[TMP14:%.*]] = load double, double* [[A5]], align 4, !nontemporal !40, !llvm.access.group !39 +// CHECK7-NEXT: [[TMP14:%.*]] = load double, double* [[A5]], align 4, !nontemporal !36, !llvm.access.group !35 // CHECK7-NEXT: [[INC:%.*]] = fadd double [[TMP14]], 1.000000e+00 -// CHECK7-NEXT: store double [[INC]], double* [[A5]], align 4, !nontemporal !40, !llvm.access.group !39 +// CHECK7-NEXT: store double [[INC]], double* [[A5]], align 4, !nontemporal !36, !llvm.access.group !35 // CHECK7-NEXT: [[CONV6:%.*]] = fptosi double [[INC]] to i16 // CHECK7-NEXT: [[TMP15:%.*]] = mul nsw i32 1, [[TMP2]] // CHECK7-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, i16* [[TMP3]], i32 [[TMP15]] // CHECK7-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i16, i16* [[ARRAYIDX]], i32 1 -// CHECK7-NEXT: store i16 [[CONV6]], i16* [[ARRAYIDX7]], align 2, !llvm.access.group !39 +// CHECK7-NEXT: store i16 [[CONV6]], i16* [[ARRAYIDX7]], align 2, !llvm.access.group !35 // 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: [[TMP16:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 +// CHECK7-NEXT: [[TMP16:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 // CHECK7-NEXT: [[ADD8:%.*]] = add i64 [[TMP16]], 1 -// CHECK7-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 -// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP41:![0-9]+]] +// CHECK7-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_IF_END:%.*]] // CHECK7: omp_if.else: @@ -11440,7 +11440,7 @@ // CHECK7-NEXT: [[TMP28:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8 // CHECK7-NEXT: [[ADD29:%.*]] = add i64 [[TMP28]], 1 // CHECK7-NEXT: store i64 [[ADD29]], i64* [[DOTOMP_IV]], align 8 -// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND14]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND14]], !llvm.loop [[LOOP39:![0-9]+]] // CHECK7: omp.inner.for.end30: // CHECK7-NEXT: br label [[OMP_IF_END]] // CHECK7: omp_if.end: @@ -11582,35 +11582,35 @@ // CHECK7-NEXT: store i64 [[TMP5]], i64* [[DOTOMP_IV]], align 8 // CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK7: omp.inner.for.cond: -// CHECK7-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !45 -// CHECK7-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !45 +// CHECK7-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 +// CHECK7-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !41 // CHECK7-NEXT: [[CMP1:%.*]] = icmp sle i64 [[TMP6]], [[TMP7]] // CHECK7-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK7: omp.inner.for.body: -// CHECK7-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !45 +// CHECK7-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 // CHECK7-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP8]], 3 // CHECK7-NEXT: [[ADD:%.*]] = add nsw i64 -10, [[MUL]] -// CHECK7-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !45 -// CHECK7-NEXT: [[TMP9:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !45 +// CHECK7-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !41 +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !41 // CHECK7-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1 -// CHECK7-NEXT: store i32 [[ADD2]], i32* [[A_ADDR]], align 4, !llvm.access.group !45 -// CHECK7-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !45 +// CHECK7-NEXT: store i32 [[ADD2]], i32* [[A_ADDR]], align 4, !llvm.access.group !41 +// CHECK7-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !41 // CHECK7-NEXT: [[CONV3:%.*]] = sext i16 [[TMP10]] to i32 // CHECK7-NEXT: [[ADD4:%.*]] = add nsw i32 [[CONV3]], 1 // CHECK7-NEXT: [[CONV5:%.*]] = trunc i32 [[ADD4]] to i16 -// CHECK7-NEXT: store i16 [[CONV5]], i16* [[CONV]], align 4, !llvm.access.group !45 +// CHECK7-NEXT: store i16 [[CONV5]], i16* [[CONV]], align 4, !llvm.access.group !41 // CHECK7-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[TMP0]], i32 0, i32 2 -// CHECK7-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !45 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !41 // CHECK7-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK7-NEXT: store i32 [[ADD6]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !45 +// CHECK7-NEXT: store i32 [[ADD6]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !41 // 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: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !45 +// CHECK7-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 // CHECK7-NEXT: [[ADD7:%.*]] = add nsw i64 [[TMP12]], 1 -// CHECK7-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !45 -// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK7-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP42:![0-9]+]] // CHECK7: omp.inner.for.end: // CHECK7-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK7: omp.loop.exit: @@ -12013,22 +12013,22 @@ // CHECK8-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 4 // CHECK8-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK8-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK8-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 -// CHECK8-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !26 -// CHECK8-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !26 -// CHECK8-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !26 -// CHECK8-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !26 -// CHECK8-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK8-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !26 -// CHECK8-NEXT: [[TMP11:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK8-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 -// CHECK8-NEXT: br i1 [[TMP12]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK8-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK8-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK8-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK8-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META22]]), !noalias !20 +// CHECK8-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK8-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !20 +// CHECK8-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !20 +// CHECK8-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !20 +// CHECK8-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !20 +// CHECK8-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !20 +// CHECK8-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !20 +// CHECK8-NEXT: [[TMP15:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96.region_id, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 1, i32 0, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !20 +// CHECK8-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK8-NEXT: br i1 [[TMP16]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK8: omp_offload.failed.i: -// CHECK8-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]] +// CHECK8-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l96() #[[ATTR4]], !noalias !20 // CHECK8-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK8: .omp_outlined..1.exit: // CHECK8-NEXT: ret i32 0 @@ -12091,32 +12091,32 @@ // CHECK8-NEXT: store i32 [[TMP5]], i32* [[DOTOMP_IV]], align 4 // CHECK8-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK8: omp.inner.for.cond: -// CHECK8-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 -// CHECK8-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !27 +// CHECK8-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 +// CHECK8-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !23 // CHECK8-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] // CHECK8-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK8: omp.inner.for.body: -// CHECK8-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK8-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK8-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP8]], 1 // CHECK8-NEXT: [[SUB:%.*]] = sub nsw i32 10, [[MUL]] -// CHECK8-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !27 -// CHECK8-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !27 -// CHECK8-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK8-NEXT: store i32 [[SUB]], i32* [[I]], align 4, !llvm.access.group !23 +// CHECK8-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTLINEAR_START]], align 8, !llvm.access.group !23 +// CHECK8-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK8-NEXT: [[MUL2:%.*]] = mul nsw i32 [[TMP10]], 3 // CHECK8-NEXT: [[CONV:%.*]] = sext i32 [[MUL2]] to i64 // CHECK8-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP9]], [[CONV]] -// CHECK8-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !27 -// CHECK8-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !27 +// CHECK8-NEXT: store i64 [[ADD]], i64* [[K1]], align 8, !llvm.access.group !23 +// CHECK8-NEXT: [[TMP11:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !23 // CHECK8-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK8-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !27 +// CHECK8-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !23 // CHECK8-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK8: omp.body.continue: // CHECK8-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK8: omp.inner.for.inc: -// CHECK8-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 +// CHECK8-NEXT: [[TMP12:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 // CHECK8-NEXT: [[ADD4:%.*]] = add nsw i32 [[TMP12]], 1 -// CHECK8-NEXT: store i32 [[ADD4]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !27 -// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK8-NEXT: store i32 [[ADD4]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !23 +// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] // CHECK8: omp.inner.for.end: // CHECK8-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK8: omp.dispatch.inc: @@ -12223,44 +12223,44 @@ // CHECK8-NEXT: store i64 [[TMP6]], i64* [[DOTOMP_IV]], align 8 // CHECK8-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK8: omp.inner.for.cond: -// CHECK8-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK8-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !30 +// CHECK8-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK8-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !26 // CHECK8-NEXT: [[CMP4:%.*]] = icmp ule i64 [[TMP7]], [[TMP8]] // CHECK8-NEXT: br i1 [[CMP4]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK8: omp.inner.for.body: -// CHECK8-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 +// CHECK8-NEXT: [[TMP9:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 // CHECK8-NEXT: [[MUL:%.*]] = mul i64 [[TMP9]], 400 // CHECK8-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK8-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !30 -// CHECK8-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !30 +// CHECK8-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !26 +// CHECK8-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTLINEAR_START]], align 4, !llvm.access.group !26 // CHECK8-NEXT: [[CONV5:%.*]] = sext i32 [[TMP10]] to i64 -// CHECK8-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK8-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !30 +// CHECK8-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK8-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !26 // CHECK8-NEXT: [[MUL6:%.*]] = mul i64 [[TMP11]], [[TMP12]] // CHECK8-NEXT: [[ADD:%.*]] = add i64 [[CONV5]], [[MUL6]] // CHECK8-NEXT: [[CONV7:%.*]] = trunc i64 [[ADD]] to i32 -// CHECK8-NEXT: store i32 [[CONV7]], i32* [[LIN2]], align 4, !llvm.access.group !30 -// CHECK8-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4, !llvm.access.group !30 +// CHECK8-NEXT: store i32 [[CONV7]], i32* [[LIN2]], align 4, !llvm.access.group !26 +// CHECK8-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTLINEAR_START1]], align 4, !llvm.access.group !26 // CHECK8-NEXT: [[CONV8:%.*]] = sext i32 [[TMP13]] to i64 -// CHECK8-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK8-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !30 +// CHECK8-NEXT: [[TMP14:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK8-NEXT: [[TMP15:%.*]] = load i64, i64* [[DOTLINEAR_STEP]], align 8, !llvm.access.group !26 // CHECK8-NEXT: [[MUL9:%.*]] = mul i64 [[TMP14]], [[TMP15]] // CHECK8-NEXT: [[ADD10:%.*]] = add i64 [[CONV8]], [[MUL9]] // CHECK8-NEXT: [[CONV11:%.*]] = trunc i64 [[ADD10]] to i32 -// CHECK8-NEXT: store i32 [[CONV11]], i32* [[A3]], align 4, !llvm.access.group !30 -// CHECK8-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !30 +// CHECK8-NEXT: store i32 [[CONV11]], i32* [[A3]], align 4, !llvm.access.group !26 +// CHECK8-NEXT: [[TMP16:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !26 // CHECK8-NEXT: [[CONV12:%.*]] = sext i16 [[TMP16]] to i32 // CHECK8-NEXT: [[ADD13:%.*]] = add nsw i32 [[CONV12]], 1 // CHECK8-NEXT: [[CONV14:%.*]] = trunc i32 [[ADD13]] to i16 -// CHECK8-NEXT: store i16 [[CONV14]], i16* [[CONV]], align 4, !llvm.access.group !30 +// CHECK8-NEXT: store i16 [[CONV14]], i16* [[CONV]], align 4, !llvm.access.group !26 // CHECK8-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK8: omp.body.continue: // CHECK8-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK8: omp.inner.for.inc: -// CHECK8-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 +// CHECK8-NEXT: [[TMP17:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 // CHECK8-NEXT: [[ADD15:%.*]] = add i64 [[TMP17]], 1 -// CHECK8-NEXT: store i64 [[ADD15]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !30 -// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK8-NEXT: store i64 [[ADD15]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !26 +// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP27:![0-9]+]] // CHECK8: omp.inner.for.end: // CHECK8-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK8: omp.loop.exit: @@ -12357,32 +12357,32 @@ // CHECK8-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4 // CHECK8-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK8: omp.inner.for.cond: -// CHECK8-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 -// CHECK8-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !33 +// CHECK8-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 +// CHECK8-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !29 // CHECK8-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] // CHECK8-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK8: omp.inner.for.body: -// CHECK8-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 +// CHECK8-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 // CHECK8-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 4 // CHECK8-NEXT: [[ADD:%.*]] = add nsw i32 6, [[MUL]] // CHECK8-NEXT: [[CONV2:%.*]] = trunc i32 [[ADD]] to i16 -// CHECK8-NEXT: store i16 [[CONV2]], i16* [[IT]], align 2, !llvm.access.group !33 -// CHECK8-NEXT: [[TMP8:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !33 +// CHECK8-NEXT: store i16 [[CONV2]], i16* [[IT]], align 2, !llvm.access.group !29 +// CHECK8-NEXT: [[TMP8:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !29 // CHECK8-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP8]], 1 -// CHECK8-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !33 -// CHECK8-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !33 +// CHECK8-NEXT: store i32 [[ADD3]], i32* [[A_ADDR]], align 4, !llvm.access.group !29 +// CHECK8-NEXT: [[TMP9:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !29 // CHECK8-NEXT: [[CONV4:%.*]] = sext i16 [[TMP9]] to i32 // CHECK8-NEXT: [[ADD5:%.*]] = add nsw i32 [[CONV4]], 1 // CHECK8-NEXT: [[CONV6:%.*]] = trunc i32 [[ADD5]] to i16 -// CHECK8-NEXT: store i16 [[CONV6]], i16* [[CONV]], align 4, !llvm.access.group !33 +// CHECK8-NEXT: store i16 [[CONV6]], i16* [[CONV]], align 4, !llvm.access.group !29 // CHECK8-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK8: omp.body.continue: // CHECK8-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK8: omp.inner.for.inc: -// CHECK8-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 +// CHECK8-NEXT: [[TMP10:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 // CHECK8-NEXT: [[ADD7:%.*]] = add nsw i32 [[TMP10]], 1 -// CHECK8-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !33 -// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK8-NEXT: store i32 [[ADD7]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !29 +// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] // CHECK8: omp.inner.for.end: // CHECK8-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK8: omp.loop.exit: @@ -12512,60 +12512,60 @@ // CHECK8: omp.dispatch.body: // CHECK8-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK8: omp.inner.for.cond: -// CHECK8-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 -// CHECK8-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: [[TMP16:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK8-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[CMP6:%.*]] = icmp sle i32 [[TMP16]], [[TMP17]] // CHECK8-NEXT: br i1 [[CMP6]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK8: omp.inner.for.body: -// CHECK8-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP18]], 1 // CHECK8-NEXT: [[SUB:%.*]] = sub nsw i32 122, [[MUL]] // CHECK8-NEXT: [[CONV:%.*]] = trunc i32 [[SUB]] to i8 -// CHECK8-NEXT: store i8 [[CONV]], i8* [[IT]], align 1, !llvm.access.group !36 -// CHECK8-NEXT: [[TMP19:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: store i8 [[CONV]], i8* [[IT]], align 1, !llvm.access.group !32 +// CHECK8-NEXT: [[TMP19:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP19]], 1 -// CHECK8-NEXT: store i32 [[ADD]], i32* [[A_ADDR]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: store i32 [[ADD]], i32* [[A_ADDR]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x float], [10 x float]* [[TMP0]], i32 0, i32 2 -// CHECK8-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: [[TMP20:%.*]] = load float, float* [[ARRAYIDX]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[CONV7:%.*]] = fpext float [[TMP20]] to double // CHECK8-NEXT: [[ADD8:%.*]] = fadd double [[CONV7]], 1.000000e+00 // CHECK8-NEXT: [[CONV9:%.*]] = fptrunc double [[ADD8]] to float -// CHECK8-NEXT: store float [[CONV9]], float* [[ARRAYIDX]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: store float [[CONV9]], float* [[ARRAYIDX]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds float, float* [[TMP2]], i32 3 -// CHECK8-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX10]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: [[TMP21:%.*]] = load float, float* [[ARRAYIDX10]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[CONV11:%.*]] = fpext float [[TMP21]] to double // CHECK8-NEXT: [[ADD12:%.*]] = fadd double [[CONV11]], 1.000000e+00 // CHECK8-NEXT: [[CONV13:%.*]] = fptrunc double [[ADD12]] to float -// CHECK8-NEXT: store float [[CONV13]], float* [[ARRAYIDX10]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: store float [[CONV13]], float* [[ARRAYIDX10]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [5 x [10 x double]], [5 x [10 x double]]* [[TMP3]], i32 0, i32 1 // CHECK8-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [10 x double], [10 x double]* [[ARRAYIDX14]], i32 0, i32 2 -// CHECK8-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX15]], align 8, !llvm.access.group !36 +// CHECK8-NEXT: [[TMP22:%.*]] = load double, double* [[ARRAYIDX15]], align 8, !llvm.access.group !32 // CHECK8-NEXT: [[ADD16:%.*]] = fadd double [[TMP22]], 1.000000e+00 -// CHECK8-NEXT: store double [[ADD16]], double* [[ARRAYIDX15]], align 8, !llvm.access.group !36 +// CHECK8-NEXT: store double [[ADD16]], double* [[ARRAYIDX15]], align 8, !llvm.access.group !32 // CHECK8-NEXT: [[TMP23:%.*]] = mul nsw i32 1, [[TMP5]] // CHECK8-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds double, double* [[TMP6]], i32 [[TMP23]] // CHECK8-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds double, double* [[ARRAYIDX17]], i32 3 -// CHECK8-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX18]], align 8, !llvm.access.group !36 +// CHECK8-NEXT: [[TMP24:%.*]] = load double, double* [[ARRAYIDX18]], align 8, !llvm.access.group !32 // CHECK8-NEXT: [[ADD19:%.*]] = fadd double [[TMP24]], 1.000000e+00 -// CHECK8-NEXT: store double [[ADD19]], double* [[ARRAYIDX18]], align 8, !llvm.access.group !36 +// CHECK8-NEXT: store double [[ADD19]], double* [[ARRAYIDX18]], align 8, !llvm.access.group !32 // CHECK8-NEXT: [[X:%.*]] = getelementptr inbounds [[STRUCT_TT:%.*]], %struct.TT* [[TMP7]], i32 0, i32 0 -// CHECK8-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: [[TMP25:%.*]] = load i64, i64* [[X]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[ADD20:%.*]] = add nsw i64 [[TMP25]], 1 -// CHECK8-NEXT: store i64 [[ADD20]], i64* [[X]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: store i64 [[ADD20]], i64* [[X]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[Y:%.*]] = getelementptr inbounds [[STRUCT_TT]], %struct.TT* [[TMP7]], i32 0, i32 1 -// CHECK8-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: [[TMP26:%.*]] = load i8, i8* [[Y]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[CONV21:%.*]] = sext i8 [[TMP26]] to i32 // CHECK8-NEXT: [[ADD22:%.*]] = add nsw i32 [[CONV21]], 1 // CHECK8-NEXT: [[CONV23:%.*]] = trunc i32 [[ADD22]] to i8 -// CHECK8-NEXT: store i8 [[CONV23]], i8* [[Y]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: store i8 [[CONV23]], i8* [[Y]], align 4, !llvm.access.group !32 // CHECK8-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK8: omp.body.continue: // CHECK8-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK8: omp.inner.for.inc: -// CHECK8-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 +// CHECK8-NEXT: [[TMP27:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 // CHECK8-NEXT: [[ADD24:%.*]] = add nsw i32 [[TMP27]], 1 -// CHECK8-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !36 -// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK8-NEXT: store i32 [[ADD24]], i32* [[DOTOMP_IV]], align 4, !llvm.access.group !32 +// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] // CHECK8: omp.inner.for.end: // CHECK8-NEXT: br label [[OMP_DISPATCH_INC:%.*]] // CHECK8: omp.dispatch.inc: @@ -13019,37 +13019,37 @@ // CHECK8-NEXT: store i64 [[TMP9]], i64* [[DOTOMP_IV]], align 8 // CHECK8-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK8: omp.inner.for.cond: -// CHECK8-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 -// CHECK8-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !39 +// CHECK8-NEXT: [[TMP10:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 +// CHECK8-NEXT: [[TMP11:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !35 // CHECK8-NEXT: [[CMP3:%.*]] = icmp ule i64 [[TMP10]], [[TMP11]] // CHECK8-NEXT: br i1 [[CMP3]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK8: omp.inner.for.body: -// CHECK8-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 +// CHECK8-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 // CHECK8-NEXT: [[MUL:%.*]] = mul i64 [[TMP12]], 400 // CHECK8-NEXT: [[SUB:%.*]] = sub i64 2000, [[MUL]] -// CHECK8-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !39 -// CHECK8-NEXT: [[TMP13:%.*]] = load i32, i32* [[B_ADDR]], align 4, !llvm.access.group !39 +// CHECK8-NEXT: store i64 [[SUB]], i64* [[IT]], align 8, !llvm.access.group !35 +// CHECK8-NEXT: [[TMP13:%.*]] = load i32, i32* [[B_ADDR]], align 4, !llvm.access.group !35 // CHECK8-NEXT: [[CONV4:%.*]] = sitofp i32 [[TMP13]] to double // CHECK8-NEXT: [[ADD:%.*]] = fadd double [[CONV4]], 1.500000e+00 // CHECK8-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK8-NEXT: store double [[ADD]], double* [[A]], align 4, !nontemporal !40, !llvm.access.group !39 +// CHECK8-NEXT: store double [[ADD]], double* [[A]], align 4, !nontemporal !36, !llvm.access.group !35 // CHECK8-NEXT: [[A5:%.*]] = getelementptr inbounds [[STRUCT_S1]], %struct.S1* [[TMP0]], i32 0, i32 0 -// CHECK8-NEXT: [[TMP14:%.*]] = load double, double* [[A5]], align 4, !nontemporal !40, !llvm.access.group !39 +// CHECK8-NEXT: [[TMP14:%.*]] = load double, double* [[A5]], align 4, !nontemporal !36, !llvm.access.group !35 // CHECK8-NEXT: [[INC:%.*]] = fadd double [[TMP14]], 1.000000e+00 -// CHECK8-NEXT: store double [[INC]], double* [[A5]], align 4, !nontemporal !40, !llvm.access.group !39 +// CHECK8-NEXT: store double [[INC]], double* [[A5]], align 4, !nontemporal !36, !llvm.access.group !35 // CHECK8-NEXT: [[CONV6:%.*]] = fptosi double [[INC]] to i16 // CHECK8-NEXT: [[TMP15:%.*]] = mul nsw i32 1, [[TMP2]] // CHECK8-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i16, i16* [[TMP3]], i32 [[TMP15]] // CHECK8-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i16, i16* [[ARRAYIDX]], i32 1 -// CHECK8-NEXT: store i16 [[CONV6]], i16* [[ARRAYIDX7]], align 2, !llvm.access.group !39 +// CHECK8-NEXT: store i16 [[CONV6]], i16* [[ARRAYIDX7]], align 2, !llvm.access.group !35 // CHECK8-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK8: omp.body.continue: // CHECK8-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK8: omp.inner.for.inc: -// CHECK8-NEXT: [[TMP16:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 +// CHECK8-NEXT: [[TMP16:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 // CHECK8-NEXT: [[ADD8:%.*]] = add i64 [[TMP16]], 1 -// CHECK8-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !39 -// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP41:![0-9]+]] +// CHECK8-NEXT: store i64 [[ADD8]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !35 +// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] // CHECK8: omp.inner.for.end: // CHECK8-NEXT: br label [[OMP_IF_END:%.*]] // CHECK8: omp_if.else: @@ -13101,7 +13101,7 @@ // CHECK8-NEXT: [[TMP28:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8 // CHECK8-NEXT: [[ADD29:%.*]] = add i64 [[TMP28]], 1 // CHECK8-NEXT: store i64 [[ADD29]], i64* [[DOTOMP_IV]], align 8 -// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND14]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND14]], !llvm.loop [[LOOP39:![0-9]+]] // CHECK8: omp.inner.for.end30: // CHECK8-NEXT: br label [[OMP_IF_END]] // CHECK8: omp_if.end: @@ -13243,35 +13243,35 @@ // CHECK8-NEXT: store i64 [[TMP5]], i64* [[DOTOMP_IV]], align 8 // CHECK8-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] // CHECK8: omp.inner.for.cond: -// CHECK8-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !45 -// CHECK8-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !45 +// CHECK8-NEXT: [[TMP6:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 +// CHECK8-NEXT: [[TMP7:%.*]] = load i64, i64* [[DOTOMP_UB]], align 8, !llvm.access.group !41 // CHECK8-NEXT: [[CMP1:%.*]] = icmp sle i64 [[TMP6]], [[TMP7]] // CHECK8-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] // CHECK8: omp.inner.for.body: -// CHECK8-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !45 +// CHECK8-NEXT: [[TMP8:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 // CHECK8-NEXT: [[MUL:%.*]] = mul nsw i64 [[TMP8]], 3 // CHECK8-NEXT: [[ADD:%.*]] = add nsw i64 -10, [[MUL]] -// CHECK8-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !45 -// CHECK8-NEXT: [[TMP9:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !45 +// CHECK8-NEXT: store i64 [[ADD]], i64* [[I]], align 8, !llvm.access.group !41 +// CHECK8-NEXT: [[TMP9:%.*]] = load i32, i32* [[A_ADDR]], align 4, !llvm.access.group !41 // CHECK8-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1 -// CHECK8-NEXT: store i32 [[ADD2]], i32* [[A_ADDR]], align 4, !llvm.access.group !45 -// CHECK8-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !45 +// CHECK8-NEXT: store i32 [[ADD2]], i32* [[A_ADDR]], align 4, !llvm.access.group !41 +// CHECK8-NEXT: [[TMP10:%.*]] = load i16, i16* [[CONV]], align 4, !llvm.access.group !41 // CHECK8-NEXT: [[CONV3:%.*]] = sext i16 [[TMP10]] to i32 // CHECK8-NEXT: [[ADD4:%.*]] = add nsw i32 [[CONV3]], 1 // CHECK8-NEXT: [[CONV5:%.*]] = trunc i32 [[ADD4]] to i16 -// CHECK8-NEXT: store i16 [[CONV5]], i16* [[CONV]], align 4, !llvm.access.group !45 +// CHECK8-NEXT: store i16 [[CONV5]], i16* [[CONV]], align 4, !llvm.access.group !41 // CHECK8-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i32], [10 x i32]* [[TMP0]], i32 0, i32 2 -// CHECK8-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !45 +// CHECK8-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4, !llvm.access.group !41 // CHECK8-NEXT: [[ADD6:%.*]] = add nsw i32 [[TMP11]], 1 -// CHECK8-NEXT: store i32 [[ADD6]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !45 +// CHECK8-NEXT: store i32 [[ADD6]], i32* [[ARRAYIDX]], align 4, !llvm.access.group !41 // CHECK8-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] // CHECK8: omp.body.continue: // CHECK8-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] // CHECK8: omp.inner.for.inc: -// CHECK8-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !45 +// CHECK8-NEXT: [[TMP12:%.*]] = load i64, i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 // CHECK8-NEXT: [[ADD7:%.*]] = add nsw i64 [[TMP12]], 1 -// CHECK8-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !45 -// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK8-NEXT: store i64 [[ADD7]], i64* [[DOTOMP_IV]], align 8, !llvm.access.group !41 +// CHECK8-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP42:![0-9]+]] // CHECK8: omp.inner.for.end: // CHECK8-NEXT: br label [[OMP_LOOP_EXIT:%.*]] // CHECK8: omp.loop.exit: Index: clang/test/OpenMP/target_parallel_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/target_parallel_reduction_task_codegen.cpp +++ clang/test/OpenMP/target_parallel_reduction_task_codegen.cpp @@ -411,61 +411,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -894,61 +898,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/target_teams_codegen.cpp =================================================================== --- clang/test/OpenMP/target_teams_codegen.cpp +++ clang/test/OpenMP/target_teams_codegen.cpp @@ -767,49 +767,53 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK1-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK1-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK1-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META22]]), !noalias !18 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META23]]), !noalias !18 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META24]]), !noalias !18 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !18 +// CHECK1-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 +// CHECK1-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !18 +// CHECK1-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK1-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: omp_offload.failed.i: -// CHECK1-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK1-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !18 // CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK1-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !24 -// CHECK1-NEXT: [[TMP30:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK1-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !18 +// CHECK1-NEXT: [[TMP38:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 // CHECK1-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK1-NEXT: store i32 [[TMP31]], i32* [[CONV4_I]], align 4, !noalias !24 -// CHECK1-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK1-NEXT: store i32 [[TMP39]], i32* [[CONV4_I]], align 4, !noalias !18 +// CHECK1-NEXT: [[TMP40:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 // CHECK1-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK1-NEXT: store i32 [[TMP33]], i32* [[CONV6_I]], align 4, !noalias !24 -// CHECK1-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !24 -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i64 [[TMP30]], i64 [[TMP32]], i64 [[TMP34]]) #[[ATTR3]] +// CHECK1-NEXT: store i32 [[TMP41]], i32* [[CONV6_I]], align 4, !noalias !18 +// CHECK1-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !18 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i64 [[TMP38]], i64 [[TMP40]], i64 [[TMP42]]) #[[ATTR3]], !noalias !18 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .omp_outlined..1.exit: // CHECK1-NEXT: ret i32 0 @@ -2150,49 +2154,53 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK2-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK2-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK2-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK2-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META22]]), !noalias !18 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META23]]), !noalias !18 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META24]]), !noalias !18 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !18 +// CHECK2-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 +// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 +// CHECK2-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !18 +// CHECK2-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK2-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: omp_offload.failed.i: -// CHECK2-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK2-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !18 // CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK2-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !24 -// CHECK2-NEXT: [[TMP30:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK2-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !18 +// CHECK2-NEXT: [[TMP38:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 // CHECK2-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK2-NEXT: store i32 [[TMP31]], i32* [[CONV4_I]], align 4, !noalias !24 -// CHECK2-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK2-NEXT: store i32 [[TMP39]], i32* [[CONV4_I]], align 4, !noalias !18 +// CHECK2-NEXT: [[TMP40:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 // CHECK2-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK2-NEXT: store i32 [[TMP33]], i32* [[CONV6_I]], align 4, !noalias !24 -// CHECK2-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !24 -// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i64 [[TMP30]], i64 [[TMP32]], i64 [[TMP34]]) #[[ATTR3]] +// CHECK2-NEXT: store i32 [[TMP41]], i32* [[CONV6_I]], align 4, !noalias !18 +// CHECK2-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !18 +// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i64 [[TMP38]], i64 [[TMP40]], i64 [[TMP42]]) #[[ATTR3]], !noalias !18 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .omp_outlined..1.exit: // CHECK2-NEXT: ret i32 0 @@ -3524,47 +3532,51 @@ // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK3-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK3-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK3-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK3-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK3-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK3-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK3-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK3-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK3-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK3-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK3-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK3-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META24]]), !noalias !19 +// CHECK3-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK3-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META25]]), !noalias !19 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK3-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !19 +// CHECK3-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !19 +// CHECK3-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK3-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK3: omp_offload.failed.i: -// CHECK3-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK3-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !19 // CHECK3-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK3-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !25 -// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK3-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK3-NEXT: store i32 [[TMP33]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !25 -// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !25 -// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i32 [[TMP30]], i32 [[TMP32]], i32 [[TMP34]]) #[[ATTR3]] +// CHECK3-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !19 +// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK3-NEXT: store i32 [[TMP39]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK3-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !19 +// CHECK3-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !19 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i32 [[TMP38]], i32 [[TMP40]], i32 [[TMP42]]) #[[ATTR3]], !noalias !19 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK3: .omp_outlined..1.exit: // CHECK3-NEXT: ret i32 0 @@ -4866,47 +4878,51 @@ // CHECK4-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK4-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK4-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK4-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK4-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK4-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK4-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK4-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK4-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK4-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK4-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK4-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK4-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META24]]), !noalias !19 +// CHECK4-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK4-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META25]]), !noalias !19 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK4-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !19 +// CHECK4-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK4-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !19 +// CHECK4-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK4-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK4: omp_offload.failed.i: -// CHECK4-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK4-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !19 // CHECK4-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK4-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !25 -// CHECK4-NEXT: [[TMP30:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK4-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK4-NEXT: store i32 [[TMP33]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !25 -// CHECK4-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !25 -// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i32 [[TMP30]], i32 [[TMP32]], i32 [[TMP34]]) #[[ATTR3]] +// CHECK4-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !19 +// CHECK4-NEXT: [[TMP38:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK4-NEXT: store i32 [[TMP39]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK4-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !19 +// CHECK4-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !19 +// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i32 [[TMP38]], i32 [[TMP40]], i32 [[TMP42]]) #[[ATTR3]], !noalias !19 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK4: .omp_outlined..1.exit: // CHECK4-NEXT: ret i32 0 @@ -8323,49 +8339,53 @@ // CHECK17-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK17-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK17-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK17-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK17-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK17-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK17-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK17-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK17-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK17-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK17-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK17-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK17-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK17-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK17-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK17-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK17-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK17-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META22]]), !noalias !18 +// CHECK17-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK17-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META23]]), !noalias !18 +// CHECK17-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK17-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META24]]), !noalias !18 +// CHECK17-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK17-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK17-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !18 +// CHECK17-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK17-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK17-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK17-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK17-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK17-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 +// CHECK17-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 +// CHECK17-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !18 +// CHECK17-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK17-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK17: omp_offload.failed.i: -// CHECK17-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK17-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !18 // CHECK17-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK17-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !24 -// CHECK17-NEXT: [[TMP30:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK17-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !18 +// CHECK17-NEXT: [[TMP38:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 // CHECK17-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK17-NEXT: store i32 [[TMP31]], i32* [[CONV4_I]], align 4, !noalias !24 -// CHECK17-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !24 -// CHECK17-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK17-NEXT: store i32 [[TMP39]], i32* [[CONV4_I]], align 4, !noalias !18 +// CHECK17-NEXT: [[TMP40:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !18 +// CHECK17-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 // CHECK17-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK17-NEXT: store i32 [[TMP33]], i32* [[CONV6_I]], align 4, !noalias !24 -// CHECK17-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !24 -// CHECK17-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i64 [[TMP30]], i64 [[TMP32]], i64 [[TMP34]]) #[[ATTR3]] +// CHECK17-NEXT: store i32 [[TMP41]], i32* [[CONV6_I]], align 4, !noalias !18 +// CHECK17-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !18 +// CHECK17-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i64 [[TMP38]], i64 [[TMP40]], i64 [[TMP42]]) #[[ATTR3]], !noalias !18 // CHECK17-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK17: .omp_outlined..1.exit: // CHECK17-NEXT: ret i32 0 @@ -9706,49 +9726,53 @@ // CHECK18-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK18-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK18-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK18-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK18-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK18-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK18-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK18-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK18-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK18-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK18-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK18-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK18-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK18-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK18-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK18-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK18-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK18-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK18-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK18-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META22]]), !noalias !18 +// CHECK18-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK18-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META23]]), !noalias !18 +// CHECK18-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK18-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META24]]), !noalias !18 +// CHECK18-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK18-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK18-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !18 +// CHECK18-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK18-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK18-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK18-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK18-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK18-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 +// CHECK18-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 +// CHECK18-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !18 +// CHECK18-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK18-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK18: omp_offload.failed.i: -// CHECK18-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK18-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !18 // CHECK18-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK18-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !24 -// CHECK18-NEXT: [[TMP30:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK18-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !18 +// CHECK18-NEXT: [[TMP38:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !18 // CHECK18-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK18-NEXT: store i32 [[TMP31]], i32* [[CONV4_I]], align 4, !noalias !24 -// CHECK18-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !24 -// CHECK18-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK18-NEXT: store i32 [[TMP39]], i32* [[CONV4_I]], align 4, !noalias !18 +// CHECK18-NEXT: [[TMP40:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !18 +// CHECK18-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !18 // CHECK18-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK18-NEXT: store i32 [[TMP33]], i32* [[CONV6_I]], align 4, !noalias !24 -// CHECK18-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !24 -// CHECK18-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i64 [[TMP30]], i64 [[TMP32]], i64 [[TMP34]]) #[[ATTR3]] +// CHECK18-NEXT: store i32 [[TMP41]], i32* [[CONV6_I]], align 4, !noalias !18 +// CHECK18-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !18 +// CHECK18-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i64 [[TMP38]], i64 [[TMP40]], i64 [[TMP42]]) #[[ATTR3]], !noalias !18 // CHECK18-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK18: .omp_outlined..1.exit: // CHECK18-NEXT: ret i32 0 @@ -11080,47 +11104,51 @@ // CHECK19-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK19-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK19-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK19-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK19-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK19-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK19-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK19-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK19-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK19-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK19-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK19-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK19-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK19-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK19-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK19-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK19-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK19-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK19-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META24]]), !noalias !19 +// CHECK19-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK19-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META25]]), !noalias !19 +// CHECK19-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK19-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !19 +// CHECK19-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK19-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK19-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK19-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK19-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK19-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !19 +// CHECK19-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK19-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK19: omp_offload.failed.i: -// CHECK19-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK19-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !19 // CHECK19-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK19-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !25 -// CHECK19-NEXT: [[TMP30:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK19-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK19-NEXT: store i32 [[TMP33]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !25 -// CHECK19-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !25 -// CHECK19-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i32 [[TMP30]], i32 [[TMP32]], i32 [[TMP34]]) #[[ATTR3]] +// CHECK19-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !19 +// CHECK19-NEXT: [[TMP38:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK19-NEXT: store i32 [[TMP39]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK19-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !19 +// CHECK19-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !19 +// CHECK19-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i32 [[TMP38]], i32 [[TMP40]], i32 [[TMP42]]) #[[ATTR3]], !noalias !19 // CHECK19-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK19: .omp_outlined..1.exit: // CHECK19-NEXT: ret i32 0 @@ -12422,47 +12450,51 @@ // CHECK20-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK20-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK20-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK20-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK20-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK20-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK20-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK20-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK20-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK20-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK20-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK20-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK20-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK20-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK20-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK20-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK20-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META16]]), !noalias !19 +// CHECK20-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK20-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META23]]), !noalias !19 +// CHECK20-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK20-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META24]]), !noalias !19 +// CHECK20-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK20-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META25]]), !noalias !19 +// CHECK20-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK20-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !19 +// CHECK20-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK20-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK20-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK20-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK20-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK20-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB1]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !19 +// CHECK20-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK20-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK20: omp_offload.failed.i: -// CHECK20-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK20-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !19 // CHECK20-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK20-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !25 -// CHECK20-NEXT: [[TMP30:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK20-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK20-NEXT: store i32 [[TMP33]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !25 -// CHECK20-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !25 -// CHECK20-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i32 [[TMP30]], i32 [[TMP32]], i32 [[TMP34]]) #[[ATTR3]] +// CHECK20-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !19 +// CHECK20-NEXT: [[TMP38:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !19 +// CHECK20-NEXT: store i32 [[TMP39]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !19 +// CHECK20-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !19 +// CHECK20-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !19 +// CHECK20-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l101(i32 [[TMP38]], i32 [[TMP40]], i32 [[TMP42]]) #[[ATTR3]], !noalias !19 // CHECK20-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK20: .omp_outlined..1.exit: // CHECK20-NEXT: ret i32 0 Index: clang/test/OpenMP/target_teams_distribute_codegen.cpp =================================================================== --- clang/test/OpenMP/target_teams_distribute_codegen.cpp +++ clang/test/OpenMP/target_teams_distribute_codegen.cpp @@ -781,50 +781,54 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK1-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]] -// CHECK1-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK1-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK1-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META12]]), !noalias !15 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META19:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META19]]), !noalias !15 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META20]]), !noalias !15 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META21]]), !noalias !15 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !15 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !15 +// CHECK1-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !15 +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !15 +// CHECK1-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]], !noalias !15 +// CHECK1-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !15 +// CHECK1-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK1-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: omp_offload.failed.i: -// CHECK1-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK1-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !15 // CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK1-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !21 -// CHECK1-NEXT: [[TMP30:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK1-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !15 +// CHECK1-NEXT: [[TMP38:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !15 // CHECK1-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK1-NEXT: store i32 [[TMP31]], i32* [[CONV4_I]], align 4, !noalias !21 -// CHECK1-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !21 -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK1-NEXT: store i32 [[TMP39]], i32* [[CONV4_I]], align 4, !noalias !15 +// CHECK1-NEXT: [[TMP40:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !15 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !15 // CHECK1-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK1-NEXT: store i32 [[TMP33]], i32* [[CONV6_I]], align 4, !noalias !21 -// CHECK1-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !21 -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i64 [[TMP30]], i64 [[TMP32]], i64 [[TMP34]]) #[[ATTR3]] +// CHECK1-NEXT: store i32 [[TMP41]], i32* [[CONV6_I]], align 4, !noalias !15 +// CHECK1-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !15 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i64 [[TMP38]], i64 [[TMP40]], i64 [[TMP42]]) #[[ATTR3]], !noalias !15 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .omp_outlined..1.exit: // CHECK1-NEXT: ret i32 0 @@ -2501,50 +2505,54 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK2-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK2-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]] -// CHECK2-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK2-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK2-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META12]]), !noalias !15 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META19:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META19]]), !noalias !15 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META20]]), !noalias !15 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META21]]), !noalias !15 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !15 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !15 +// CHECK2-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !15 +// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !15 +// CHECK2-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]], !noalias !15 +// CHECK2-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !15 +// CHECK2-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK2-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: omp_offload.failed.i: -// CHECK2-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK2-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !15 // CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK2-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !21 -// CHECK2-NEXT: [[TMP30:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK2-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !15 +// CHECK2-NEXT: [[TMP38:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !15 // CHECK2-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK2-NEXT: store i32 [[TMP31]], i32* [[CONV4_I]], align 4, !noalias !21 -// CHECK2-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !21 -// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK2-NEXT: store i32 [[TMP39]], i32* [[CONV4_I]], align 4, !noalias !15 +// CHECK2-NEXT: [[TMP40:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !15 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !15 // CHECK2-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK2-NEXT: store i32 [[TMP33]], i32* [[CONV6_I]], align 4, !noalias !21 -// CHECK2-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !21 -// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i64 [[TMP30]], i64 [[TMP32]], i64 [[TMP34]]) #[[ATTR3]] +// CHECK2-NEXT: store i32 [[TMP41]], i32* [[CONV6_I]], align 4, !noalias !15 +// CHECK2-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !15 +// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i64 [[TMP38]], i64 [[TMP40]], i64 [[TMP42]]) #[[ATTR3]], !noalias !15 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .omp_outlined..1.exit: // CHECK2-NEXT: ret i32 0 @@ -4213,48 +4221,52 @@ // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK3-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK3-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK3-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK3-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK3-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK3-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]] -// CHECK3-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK3-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK3-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK3-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK3-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META20]]), !noalias !16 +// CHECK3-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK3-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META21]]), !noalias !16 +// CHECK3-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK3-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META22]]), !noalias !16 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK3-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !16 +// CHECK3-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !16 +// CHECK3-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]], !noalias !16 +// CHECK3-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !16 +// CHECK3-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK3-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK3: omp_offload.failed.i: -// CHECK3-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK3-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !16 // CHECK3-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK3-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !22 -// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK3-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK3-NEXT: store i32 [[TMP33]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !22 -// CHECK3-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !22 -// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i32 [[TMP30]], i32 [[TMP32]], i32 [[TMP34]]) #[[ATTR3]] +// CHECK3-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !16 +// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !16 +// CHECK3-NEXT: store i32 [[TMP39]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !16 +// CHECK3-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !16 +// CHECK3-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !16 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i32 [[TMP38]], i32 [[TMP40]], i32 [[TMP42]]) #[[ATTR3]], !noalias !16 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK3: .omp_outlined..1.exit: // CHECK3-NEXT: ret i32 0 @@ -5895,48 +5907,52 @@ // CHECK4-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK4-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK4-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK4-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK4-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK4-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK4-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]] -// CHECK4-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK4-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK4-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK4-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK4-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META20]]), !noalias !16 +// CHECK4-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK4-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META21]]), !noalias !16 +// CHECK4-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK4-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META22]]), !noalias !16 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK4-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !16 +// CHECK4-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK4-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !16 +// CHECK4-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]], !noalias !16 +// CHECK4-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !16 +// CHECK4-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK4-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK4: omp_offload.failed.i: -// CHECK4-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK4-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !16 // CHECK4-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK4-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !22 -// CHECK4-NEXT: [[TMP30:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK4-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK4-NEXT: store i32 [[TMP33]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !22 -// CHECK4-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !22 -// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i32 [[TMP30]], i32 [[TMP32]], i32 [[TMP34]]) #[[ATTR3]] +// CHECK4-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !16 +// CHECK4-NEXT: [[TMP38:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !16 +// CHECK4-NEXT: store i32 [[TMP39]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !16 +// CHECK4-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !16 +// CHECK4-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !16 +// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i32 [[TMP38]], i32 [[TMP40]], i32 [[TMP42]]) #[[ATTR3]], !noalias !16 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK4: .omp_outlined..1.exit: // CHECK4-NEXT: ret i32 0 @@ -10931,50 +10947,54 @@ // CHECK17-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK17-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK17-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK17-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK17-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 -// CHECK17-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK17-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK17-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK17-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK17-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK17-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK17-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK17-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK17-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK17-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]] -// CHECK17-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK17-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK17-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK17-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK17-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META12]]), !noalias !15 +// CHECK17-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META19:![0-9]+]]) +// CHECK17-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META19]]), !noalias !15 +// CHECK17-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK17-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META20]]), !noalias !15 +// CHECK17-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK17-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META21]]), !noalias !15 +// CHECK17-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !15 +// CHECK17-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK17-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !15 +// CHECK17-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK17-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK17-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK17-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK17-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK17-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !15 +// CHECK17-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !15 +// CHECK17-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]], !noalias !15 +// CHECK17-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !15 +// CHECK17-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK17-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK17: omp_offload.failed.i: -// CHECK17-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK17-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !15 // CHECK17-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK17-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !21 -// CHECK17-NEXT: [[TMP30:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK17-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !15 +// CHECK17-NEXT: [[TMP38:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !15 // CHECK17-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK17-NEXT: store i32 [[TMP31]], i32* [[CONV4_I]], align 4, !noalias !21 -// CHECK17-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !21 -// CHECK17-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK17-NEXT: store i32 [[TMP39]], i32* [[CONV4_I]], align 4, !noalias !15 +// CHECK17-NEXT: [[TMP40:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !15 +// CHECK17-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !15 // CHECK17-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK17-NEXT: store i32 [[TMP33]], i32* [[CONV6_I]], align 4, !noalias !21 -// CHECK17-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !21 -// CHECK17-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i64 [[TMP30]], i64 [[TMP32]], i64 [[TMP34]]) #[[ATTR3]] +// CHECK17-NEXT: store i32 [[TMP41]], i32* [[CONV6_I]], align 4, !noalias !15 +// CHECK17-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !15 +// CHECK17-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i64 [[TMP38]], i64 [[TMP40]], i64 [[TMP42]]) #[[ATTR3]], !noalias !15 // CHECK17-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK17: .omp_outlined..1.exit: // CHECK17-NEXT: ret i32 0 @@ -12651,50 +12671,54 @@ // CHECK18-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK18-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK18-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK18-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]]) -// CHECK18-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 -// CHECK18-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK18-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK18-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK18-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK18-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK18-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK18-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK18-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK18-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK18-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]] -// CHECK18-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK18-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK18-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK18-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK18-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META12]]), !noalias !15 +// CHECK18-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META19:![0-9]+]]) +// CHECK18-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META19]]), !noalias !15 +// CHECK18-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK18-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META20]]), !noalias !15 +// CHECK18-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK18-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META21]]), !noalias !15 +// CHECK18-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !15 +// CHECK18-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK18-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !15 +// CHECK18-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK18-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK18-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK18-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK18-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK18-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !15 +// CHECK18-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !15 +// CHECK18-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]], !noalias !15 +// CHECK18-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !15 +// CHECK18-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK18-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK18: omp_offload.failed.i: -// CHECK18-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK18-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !15 // CHECK18-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK18-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !21 -// CHECK18-NEXT: [[TMP30:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK18-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !15 +// CHECK18-NEXT: [[TMP38:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !15 // CHECK18-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK18-NEXT: store i32 [[TMP31]], i32* [[CONV4_I]], align 4, !noalias !21 -// CHECK18-NEXT: [[TMP32:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !21 -// CHECK18-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK18-NEXT: store i32 [[TMP39]], i32* [[CONV4_I]], align 4, !noalias !15 +// CHECK18-NEXT: [[TMP40:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !15 +// CHECK18-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !15 // CHECK18-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK18-NEXT: store i32 [[TMP33]], i32* [[CONV6_I]], align 4, !noalias !21 -// CHECK18-NEXT: [[TMP34:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !21 -// CHECK18-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i64 [[TMP30]], i64 [[TMP32]], i64 [[TMP34]]) #[[ATTR3]] +// CHECK18-NEXT: store i32 [[TMP41]], i32* [[CONV6_I]], align 4, !noalias !15 +// CHECK18-NEXT: [[TMP42:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !15 +// CHECK18-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i64 [[TMP38]], i64 [[TMP40]], i64 [[TMP42]]) #[[ATTR3]], !noalias !15 // CHECK18-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK18: .omp_outlined..1.exit: // CHECK18-NEXT: ret i32 0 @@ -14363,48 +14387,52 @@ // CHECK19-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK19-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK19-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK19-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK19-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK19-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK19-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK19-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK19-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK19-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK19-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK19-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK19-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK19-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]] -// CHECK19-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK19-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK19-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK19-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK19-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK19-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK19-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META20]]), !noalias !16 +// CHECK19-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK19-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META21]]), !noalias !16 +// CHECK19-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK19-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META22]]), !noalias !16 +// CHECK19-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK19-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !16 +// CHECK19-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK19-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK19-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK19-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK19-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK19-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !16 +// CHECK19-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]], !noalias !16 +// CHECK19-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !16 +// CHECK19-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK19-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK19: omp_offload.failed.i: -// CHECK19-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK19-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !16 // CHECK19-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK19-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !22 -// CHECK19-NEXT: [[TMP30:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK19-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK19-NEXT: store i32 [[TMP33]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !22 -// CHECK19-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !22 -// CHECK19-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i32 [[TMP30]], i32 [[TMP32]], i32 [[TMP34]]) #[[ATTR3]] +// CHECK19-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !16 +// CHECK19-NEXT: [[TMP38:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !16 +// CHECK19-NEXT: store i32 [[TMP39]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !16 +// CHECK19-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !16 +// CHECK19-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !16 +// CHECK19-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i32 [[TMP38]], i32 [[TMP40]], i32 [[TMP42]]) #[[ATTR3]], !noalias !16 // CHECK19-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK19: .omp_outlined..1.exit: // CHECK19-NEXT: ret i32 0 @@ -16045,48 +16073,52 @@ // CHECK20-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK20-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK20-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK20-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK20-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK20-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]] -// CHECK20-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK20-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK20-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK20-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK20-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK20-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK20-NEXT: [[TMP26:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK20-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]] -// CHECK20-NEXT: [[TMP27:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 [[TMP26]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]] -// CHECK20-NEXT: [[TMP28:%.*]] = icmp ne i32 [[TMP27]], 0 -// CHECK20-NEXT: br i1 [[TMP28]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK20-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK20-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META13]]), !noalias !16 +// CHECK20-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK20-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META20]]), !noalias !16 +// CHECK20-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK20-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META21]]), !noalias !16 +// CHECK20-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK20-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META22]]), !noalias !16 +// CHECK20-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK20-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR3]], !noalias !16 +// CHECK20-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK20-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK20-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK20-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK20-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK20-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP34:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !16 +// CHECK20-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR3]], !noalias !16 +// CHECK20-NEXT: [[TMP35:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 [[TMP34]], i32 0, i8* null, i32 0, i8* null) #[[ATTR3]], !noalias !16 +// CHECK20-NEXT: [[TMP36:%.*]] = icmp ne i32 [[TMP35]], 0 +// CHECK20-NEXT: br i1 [[TMP36]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK20: omp_offload.failed.i: -// CHECK20-NEXT: [[TMP29:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK20-NEXT: [[TMP37:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !16 // CHECK20-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK20-NEXT: store i16 [[TMP29]], i16* [[CONV_I]], align 2, !noalias !22 -// CHECK20-NEXT: [[TMP30:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP31:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK20-NEXT: store i32 [[TMP31]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP32:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK20-NEXT: store i32 [[TMP33]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !22 -// CHECK20-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !22 -// CHECK20-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i32 [[TMP30]], i32 [[TMP32]], i32 [[TMP34]]) #[[ATTR3]] +// CHECK20-NEXT: store i16 [[TMP37]], i16* [[CONV_I]], align 2, !noalias !16 +// CHECK20-NEXT: [[TMP38:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP39:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !16 +// CHECK20-NEXT: store i32 [[TMP39]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP40:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP41:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !16 +// CHECK20-NEXT: store i32 [[TMP41]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !16 +// CHECK20-NEXT: [[TMP42:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !16 +// CHECK20-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l103(i32 [[TMP38]], i32 [[TMP40]], i32 [[TMP42]]) #[[ATTR3]], !noalias !16 // CHECK20-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK20: .omp_outlined..1.exit: // CHECK20-NEXT: ret i32 0 Index: clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp +++ clang/test/OpenMP/target_teams_distribute_parallel_for_reduction_task_codegen.cpp @@ -811,61 +811,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -1743,61 +1747,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp =================================================================== --- clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp +++ clang/test/OpenMP/target_teams_distribute_simd_codegen.cpp @@ -769,49 +769,53 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !26 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !26 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK1-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]] -// CHECK1-NEXT: [[TMP26:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK1-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK1-NEXT: br i1 [[TMP27]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META24]]), !noalias !20 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META25]]), !noalias !20 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META26]]), !noalias !20 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !20 +// CHECK1-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !20 +// CHECK1-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]], !noalias !20 +// CHECK1-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !20 +// CHECK1-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 +// CHECK1-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK1: omp_offload.failed.i: -// CHECK1-NEXT: [[TMP28:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK1-NEXT: [[TMP36:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !20 // CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK1-NEXT: store i16 [[TMP28]], i16* [[CONV_I]], align 2, !noalias !26 -// CHECK1-NEXT: [[TMP29:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK1-NEXT: store i16 [[TMP36]], i16* [[CONV_I]], align 2, !noalias !20 +// CHECK1-NEXT: [[TMP37:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !20 // CHECK1-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK1-NEXT: store i32 [[TMP30]], i32* [[CONV4_I]], align 4, !noalias !26 -// CHECK1-NEXT: [[TMP31:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !26 -// CHECK1-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK1-NEXT: store i32 [[TMP38]], i32* [[CONV4_I]], align 4, !noalias !20 +// CHECK1-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !20 // CHECK1-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK1-NEXT: store i32 [[TMP32]], i32* [[CONV6_I]], align 4, !noalias !26 -// CHECK1-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !26 -// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i64 [[TMP29]], i64 [[TMP31]], i64 [[TMP33]]) #[[ATTR4]] +// CHECK1-NEXT: store i32 [[TMP40]], i32* [[CONV6_I]], align 4, !noalias !20 +// CHECK1-NEXT: [[TMP41:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !20 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i64 [[TMP37]], i64 [[TMP39]], i64 [[TMP41]]) #[[ATTR4]], !noalias !20 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK1: .omp_outlined..1.exit: // CHECK1-NEXT: ret i32 0 @@ -2508,49 +2512,53 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !26 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !26 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK2-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]] -// CHECK2-NEXT: [[TMP26:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK2-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK2-NEXT: br i1 [[TMP27]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META24]]), !noalias !20 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META25]]), !noalias !20 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META26]]), !noalias !20 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !20 +// CHECK2-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !20 +// CHECK2-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]], !noalias !20 +// CHECK2-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !20 +// CHECK2-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 +// CHECK2-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK2: omp_offload.failed.i: -// CHECK2-NEXT: [[TMP28:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK2-NEXT: [[TMP36:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !20 // CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK2-NEXT: store i16 [[TMP28]], i16* [[CONV_I]], align 2, !noalias !26 -// CHECK2-NEXT: [[TMP29:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK2-NEXT: store i16 [[TMP36]], i16* [[CONV_I]], align 2, !noalias !20 +// CHECK2-NEXT: [[TMP37:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !20 // CHECK2-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK2-NEXT: store i32 [[TMP30]], i32* [[CONV4_I]], align 4, !noalias !26 -// CHECK2-NEXT: [[TMP31:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !26 -// CHECK2-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK2-NEXT: store i32 [[TMP38]], i32* [[CONV4_I]], align 4, !noalias !20 +// CHECK2-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !20 // CHECK2-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK2-NEXT: store i32 [[TMP32]], i32* [[CONV6_I]], align 4, !noalias !26 -// CHECK2-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !26 -// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i64 [[TMP29]], i64 [[TMP31]], i64 [[TMP33]]) #[[ATTR4]] +// CHECK2-NEXT: store i32 [[TMP40]], i32* [[CONV6_I]], align 4, !noalias !20 +// CHECK2-NEXT: [[TMP41:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !20 +// CHECK2-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i64 [[TMP37]], i64 [[TMP39]], i64 [[TMP41]]) #[[ATTR4]], !noalias !20 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK2: .omp_outlined..1.exit: // CHECK2-NEXT: ret i32 0 @@ -4240,47 +4248,51 @@ // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK3-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK3-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK3-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK3-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]] -// CHECK3-NEXT: [[TMP26:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK3-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK3-NEXT: br i1 [[TMP27]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META18:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META18]]), !noalias !21 +// CHECK3-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK3-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META25]]), !noalias !21 +// CHECK3-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK3-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META26]]), !noalias !21 +// CHECK3-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK3-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META27]]), !noalias !21 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK3-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !21 +// CHECK3-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !21 +// CHECK3-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]], !noalias !21 +// CHECK3-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !21 +// CHECK3-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 +// CHECK3-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK3: omp_offload.failed.i: -// CHECK3-NEXT: [[TMP28:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK3-NEXT: [[TMP36:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !21 // CHECK3-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK3-NEXT: store i16 [[TMP28]], i16* [[CONV_I]], align 2, !noalias !27 -// CHECK3-NEXT: [[TMP29:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK3-NEXT: store i32 [[TMP30]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK3-NEXT: store i32 [[TMP32]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !27 -// CHECK3-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !27 -// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i32 [[TMP29]], i32 [[TMP31]], i32 [[TMP33]]) #[[ATTR4]] +// CHECK3-NEXT: store i16 [[TMP36]], i16* [[CONV_I]], align 2, !noalias !21 +// CHECK3-NEXT: [[TMP37:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !21 +// CHECK3-NEXT: store i32 [[TMP38]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !21 +// CHECK3-NEXT: store i32 [[TMP40]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !21 +// CHECK3-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !21 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i32 [[TMP37]], i32 [[TMP39]], i32 [[TMP41]]) #[[ATTR4]], !noalias !21 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK3: .omp_outlined..1.exit: // CHECK3-NEXT: ret i32 0 @@ -5945,47 +5957,51 @@ // CHECK4-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK4-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK4-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK4-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK4-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]] -// CHECK4-NEXT: [[TMP26:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK4-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK4-NEXT: br i1 [[TMP27]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META18:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META18]]), !noalias !21 +// CHECK4-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK4-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META25]]), !noalias !21 +// CHECK4-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK4-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META26]]), !noalias !21 +// CHECK4-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK4-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META27]]), !noalias !21 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK4-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !21 +// CHECK4-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK4-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !21 +// CHECK4-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]], !noalias !21 +// CHECK4-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !21 +// CHECK4-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 +// CHECK4-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK4: omp_offload.failed.i: -// CHECK4-NEXT: [[TMP28:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK4-NEXT: [[TMP36:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !21 // CHECK4-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK4-NEXT: store i16 [[TMP28]], i16* [[CONV_I]], align 2, !noalias !27 -// CHECK4-NEXT: [[TMP29:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK4-NEXT: store i32 [[TMP30]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK4-NEXT: store i32 [[TMP32]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !27 -// CHECK4-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !27 -// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i32 [[TMP29]], i32 [[TMP31]], i32 [[TMP33]]) #[[ATTR4]] +// CHECK4-NEXT: store i16 [[TMP36]], i16* [[CONV_I]], align 2, !noalias !21 +// CHECK4-NEXT: [[TMP37:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !21 +// CHECK4-NEXT: store i32 [[TMP38]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !21 +// CHECK4-NEXT: store i32 [[TMP40]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !21 +// CHECK4-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !21 +// CHECK4-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i32 [[TMP37]], i32 [[TMP39]], i32 [[TMP41]]) #[[ATTR4]], !noalias !21 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK4: .omp_outlined..1.exit: // CHECK4-NEXT: ret i32 0 @@ -7657,49 +7673,53 @@ // CHECK5-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK5-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK5-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !26 -// CHECK5-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 -// CHECK5-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 -// CHECK5-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !26 -// CHECK5-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK5-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK5-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK5-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK5-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK5-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK5-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK5-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK5-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]] -// CHECK5-NEXT: [[TMP26:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK5-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK5-NEXT: br i1 [[TMP27]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK5-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK5-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META24]]), !noalias !20 +// CHECK5-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK5-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META25]]), !noalias !20 +// CHECK5-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK5-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META26]]), !noalias !20 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK5-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK5-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !20 +// CHECK5-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK5-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK5-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK5-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK5-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK5-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !20 +// CHECK5-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]], !noalias !20 +// CHECK5-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !20 +// CHECK5-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 +// CHECK5-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK5: omp_offload.failed.i: -// CHECK5-NEXT: [[TMP28:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK5-NEXT: [[TMP36:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !20 // CHECK5-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK5-NEXT: store i16 [[TMP28]], i16* [[CONV_I]], align 2, !noalias !26 -// CHECK5-NEXT: [[TMP29:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK5-NEXT: store i16 [[TMP36]], i16* [[CONV_I]], align 2, !noalias !20 +// CHECK5-NEXT: [[TMP37:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !20 // CHECK5-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK5-NEXT: store i32 [[TMP30]], i32* [[CONV4_I]], align 4, !noalias !26 -// CHECK5-NEXT: [[TMP31:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !26 -// CHECK5-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK5-NEXT: store i32 [[TMP38]], i32* [[CONV4_I]], align 4, !noalias !20 +// CHECK5-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !20 // CHECK5-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK5-NEXT: store i32 [[TMP32]], i32* [[CONV6_I]], align 4, !noalias !26 -// CHECK5-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !26 -// CHECK5-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i64 [[TMP29]], i64 [[TMP31]], i64 [[TMP33]]) #[[ATTR4]] +// CHECK5-NEXT: store i32 [[TMP40]], i32* [[CONV6_I]], align 4, !noalias !20 +// CHECK5-NEXT: [[TMP41:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !20 +// CHECK5-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i64 [[TMP37]], i64 [[TMP39]], i64 [[TMP41]]) #[[ATTR4]], !noalias !20 // CHECK5-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK5: .omp_outlined..1.exit: // CHECK5-NEXT: ret i32 0 @@ -9473,49 +9493,53 @@ // CHECK6-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK6-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK6-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META24:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !26 -// CHECK6-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 -// CHECK6-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 -// CHECK6-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !26 -// CHECK6-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK6-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK6-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i64 0, i64 0 -// CHECK6-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i64 0, i64 0 -// CHECK6-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i64 0, i64 0 -// CHECK6-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK6-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK6-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK6-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]] -// CHECK6-NEXT: [[TMP26:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK6-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK6-NEXT: br i1 [[TMP27]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK6-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META24:![0-9]+]]) +// CHECK6-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META24]]), !noalias !20 +// CHECK6-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK6-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META25]]), !noalias !20 +// CHECK6-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK6-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META26]]), !noalias !20 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK6-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK6-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !20 +// CHECK6-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i64 0, i64 0 +// CHECK6-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i64 0, i64 0 +// CHECK6-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i64 0, i64 0 +// CHECK6-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK6-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK6-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !20 +// CHECK6-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]], !noalias !20 +// CHECK6-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !20 +// CHECK6-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 +// CHECK6-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK6: omp_offload.failed.i: -// CHECK6-NEXT: [[TMP28:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK6-NEXT: [[TMP36:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !20 // CHECK6-NEXT: [[CONV_I:%.*]] = bitcast i64* [[AA_CASTED_I]] to i16* -// CHECK6-NEXT: store i16 [[TMP28]], i16* [[CONV_I]], align 2, !noalias !26 -// CHECK6-NEXT: [[TMP29:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP23]], align 4 +// CHECK6-NEXT: store i16 [[TMP36]], i16* [[CONV_I]], align 2, !noalias !20 +// CHECK6-NEXT: [[TMP37:%.*]] = load i64, i64* [[AA_CASTED_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !20 // CHECK6-NEXT: [[CONV4_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED_I]] to i32* -// CHECK6-NEXT: store i32 [[TMP30]], i32* [[CONV4_I]], align 4, !noalias !26 -// CHECK6-NEXT: [[TMP31:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !26 -// CHECK6-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP24]], align 4 +// CHECK6-NEXT: store i32 [[TMP38]], i32* [[CONV4_I]], align 4, !noalias !20 +// CHECK6-NEXT: [[TMP39:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !20 // CHECK6-NEXT: [[CONV6_I:%.*]] = bitcast i64* [[DOTCAPTURE_EXPR__CASTED5_I]] to i32* -// CHECK6-NEXT: store i32 [[TMP32]], i32* [[CONV6_I]], align 4, !noalias !26 -// CHECK6-NEXT: [[TMP33:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !26 -// CHECK6-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i64 [[TMP29]], i64 [[TMP31]], i64 [[TMP33]]) #[[ATTR4]] +// CHECK6-NEXT: store i32 [[TMP40]], i32* [[CONV6_I]], align 4, !noalias !20 +// CHECK6-NEXT: [[TMP41:%.*]] = load i64, i64* [[DOTCAPTURE_EXPR__CASTED5_I]], align 8, !noalias !20 +// CHECK6-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i64 [[TMP37]], i64 [[TMP39]], i64 [[TMP41]]) #[[ATTR4]], !noalias !20 // CHECK6-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK6: .omp_outlined..1.exit: // CHECK6-NEXT: ret i32 0 @@ -11282,47 +11306,51 @@ // CHECK7-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK7-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK7-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK7-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK7-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK7-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK7-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK7-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK7-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK7-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK7-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK7-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK7-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]] -// CHECK7-NEXT: [[TMP26:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK7-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK7-NEXT: br i1 [[TMP27]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK7-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META18:![0-9]+]]) +// CHECK7-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META18]]), !noalias !21 +// CHECK7-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK7-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META25]]), !noalias !21 +// CHECK7-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK7-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META26]]), !noalias !21 +// CHECK7-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK7-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META27]]), !noalias !21 +// CHECK7-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK7-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !21 +// CHECK7-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK7-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK7-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK7-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK7-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK7-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !21 +// CHECK7-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]], !noalias !21 +// CHECK7-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !21 +// CHECK7-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 +// CHECK7-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK7: omp_offload.failed.i: -// CHECK7-NEXT: [[TMP28:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK7-NEXT: [[TMP36:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !21 // CHECK7-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK7-NEXT: store i16 [[TMP28]], i16* [[CONV_I]], align 2, !noalias !27 -// CHECK7-NEXT: [[TMP29:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK7-NEXT: store i32 [[TMP30]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK7-NEXT: store i32 [[TMP32]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !27 -// CHECK7-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !27 -// CHECK7-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i32 [[TMP29]], i32 [[TMP31]], i32 [[TMP33]]) #[[ATTR4]] +// CHECK7-NEXT: store i16 [[TMP36]], i16* [[CONV_I]], align 2, !noalias !21 +// CHECK7-NEXT: [[TMP37:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !21 +// CHECK7-NEXT: store i32 [[TMP38]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !21 +// CHECK7-NEXT: store i32 [[TMP40]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !21 +// CHECK7-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !21 +// CHECK7-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i32 [[TMP37]], i32 [[TMP39]], i32 [[TMP41]]) #[[ATTR4]], !noalias !21 // CHECK7-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK7: .omp_outlined..1.exit: // CHECK7-NEXT: ret i32 0 @@ -13064,47 +13092,51 @@ // CHECK8-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK8-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK8-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META21:![0-9]+]]) -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK8-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK8-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* -// CHECK8-NEXT: call void [[TMP15]](i8* [[TMP14]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]] -// CHECK8-NEXT: [[TMP16:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP17:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP18:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP19:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP20:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP17]], i32 0, i32 0 -// CHECK8-NEXT: [[TMP21:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP18]], i32 0, i32 0 -// CHECK8-NEXT: [[TMP22:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP19]], i32 0, i32 0 -// CHECK8-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK8-NEXT: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK8-NEXT: [[TMP25:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK8-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]] -// CHECK8-NEXT: [[TMP26:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP20]], i8** [[TMP21]], i64* [[TMP22]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP25]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]] -// CHECK8-NEXT: [[TMP27:%.*]] = icmp ne i32 [[TMP26]], 0 -// CHECK8-NEXT: br i1 [[TMP27]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] +// CHECK8-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META18:![0-9]+]]) +// CHECK8-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META18]]), !noalias !21 +// CHECK8-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META25:![0-9]+]]) +// CHECK8-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META25]]), !noalias !21 +// CHECK8-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK8-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META26]]), !noalias !21 +// CHECK8-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK8-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META27]]), !noalias !21 +// CHECK8-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i16**, [3 x i8*]**, [3 x i8*]**, [3 x i64]**)* +// CHECK8-NEXT: call void [[TMP23]](i8* [[TMP22]], i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]]) #[[ATTR4]], !noalias !21 +// CHECK8-NEXT: [[TMP24:%.*]] = load i16*, i16** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP25:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP26:%.*]] = load [3 x i8*]*, [3 x i8*]** [[DOTFIRSTPRIV_PTR_ADDR2_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP27:%.*]] = load [3 x i64]*, [3 x i64]** [[DOTFIRSTPRIV_PTR_ADDR3_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP28:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP25]], i32 0, i32 0 +// CHECK8-NEXT: [[TMP29:%.*]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[TMP26]], i32 0, i32 0 +// CHECK8-NEXT: [[TMP30:%.*]] = getelementptr inbounds [3 x i64], [3 x i64]* [[TMP27]], i32 0, i32 0 +// CHECK8-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK8-NEXT: [[TMP32:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK8-NEXT: [[TMP33:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !21 +// CHECK8-NEXT: call void @__kmpc_push_target_tripcount_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i64 10) #[[ATTR4]], !noalias !21 +// CHECK8-NEXT: [[TMP34:%.*]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @[[GLOB2]], i64 -1, i8* @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97.region_id, i32 3, i8** [[TMP28]], i8** [[TMP29]], i64* [[TMP30]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* @.offload_maptypes, i32 0, i32 0), i8** null, i8** null, i32 [[TMP33]], i32 1, i32 0, i8* null, i32 0, i8* null) #[[ATTR4]], !noalias !21 +// CHECK8-NEXT: [[TMP35:%.*]] = icmp ne i32 [[TMP34]], 0 +// CHECK8-NEXT: br i1 [[TMP35]], label [[OMP_OFFLOAD_FAILED_I:%.*]], label [[DOTOMP_OUTLINED__1_EXIT:%.*]] // CHECK8: omp_offload.failed.i: -// CHECK8-NEXT: [[TMP28:%.*]] = load i16, i16* [[TMP16]], align 2 +// CHECK8-NEXT: [[TMP36:%.*]] = load i16, i16* [[TMP24]], align 2, !noalias !21 // CHECK8-NEXT: [[CONV_I:%.*]] = bitcast i32* [[AA_CASTED_I]] to i16* -// CHECK8-NEXT: store i16 [[TMP28]], i16* [[CONV_I]], align 2, !noalias !27 -// CHECK8-NEXT: [[TMP29:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP30:%.*]] = load i32, i32* [[TMP23]], align 4 -// CHECK8-NEXT: store i32 [[TMP30]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP32:%.*]] = load i32, i32* [[TMP24]], align 4 -// CHECK8-NEXT: store i32 [[TMP32]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !27 -// CHECK8-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !27 -// CHECK8-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i32 [[TMP29]], i32 [[TMP31]], i32 [[TMP33]]) #[[ATTR4]] +// CHECK8-NEXT: store i16 [[TMP36]], i16* [[CONV_I]], align 2, !noalias !21 +// CHECK8-NEXT: [[TMP37:%.*]] = load i32, i32* [[AA_CASTED_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP38:%.*]] = load i32, i32* [[TMP31]], align 4, !noalias !21 +// CHECK8-NEXT: store i32 [[TMP38]], i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP40:%.*]] = load i32, i32* [[TMP32]], align 4, !noalias !21 +// CHECK8-NEXT: store i32 [[TMP40]], i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !21 +// CHECK8-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR__CASTED4_I]], align 4, !noalias !21 +// CHECK8-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l97(i32 [[TMP37]], i32 [[TMP39]], i32 [[TMP41]]) #[[ATTR4]], !noalias !21 // CHECK8-NEXT: br label [[DOTOMP_OUTLINED__1_EXIT]] // CHECK8: .omp_outlined..1.exit: // CHECK8-NEXT: ret i32 0 Index: clang/test/OpenMP/task_codegen.cpp =================================================================== --- clang/test/OpenMP/task_codegen.cpp +++ clang/test/OpenMP/task_codegen.cpp @@ -482,28 +482,28 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i32 15, i32* @a, align 4 -// CHECK1-NEXT: [[TMP11:%.*]] = load i32, i32* @a, align 4 -// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP11]] to i8 -// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP10]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP13:%.*]] = load i8*, i8** [[TMP12]], align 8 -// CHECK1-NEXT: store i8 [[CONV_I]], i8* [[TMP13]], align 1 -// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP10]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP15:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP14]], align 8 -// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP15]], i64 0, i64 0 +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META8:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META8]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i32 15, i32* @a, align 4, !noalias !6 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, i32* @a, align 4, !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP15]] to i8 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP14]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP17:%.*]] = load i8*, i8** [[TMP16]], align 8, !noalias !6 +// CHECK1-NEXT: store i8 [[CONV_I]], i8* [[TMP17]], align 1, !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP14]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP19:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP18]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP19]], i64 0, i64 0 // CHECK1-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[ARRAYIDX_I]], i32 0, i32 0 -// CHECK1-NEXT: store i32 10, i32* [[A_I]], align 4 +// CHECK1-NEXT: store i32 10, i32* [[A_I]], align 4, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -528,23 +528,23 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !22 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !22 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !22 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !22 -// CHECK1-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !22 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !22 -// CHECK1-NEXT: store i32 15, i32* @a, align 4 -// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], %struct.anon.0* [[TMP10]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP12:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP11]], align 8 -// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP12]], i64 0, i64 1 +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META9]]), !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META14]]), !noalias !12 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 +// CHECK1-NEXT: store i32 15, i32* @a, align 4, !noalias !12 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], %struct.anon.0* [[TMP14]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP16:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP15]], align 8, !noalias !12 +// CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP16]], i64 0, i64 1 // CHECK1-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[ARRAYIDX_I]], i32 0, i32 0 -// CHECK1-NEXT: store i32 10, i32* [[A_I]], align 4 +// CHECK1-NEXT: store i32 10, i32* [[A_I]], align 4, !noalias !12 // CHECK1-NEXT: ret i32 0 // // @@ -570,42 +570,42 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.2* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.3* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK1-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP12]], %struct.anon.2** null, i64 0, metadata [[META20]]), !noalias !18 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store %struct.anon.2* [[TMP13]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !18 +// CHECK1-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK1-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK1-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK1-NEXT: ] // CHECK1: .untied.done..i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK1-NEXT: br label [[CLEANUP_I:%.*]] // CHECK1: .untied.jmp..i: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK1-NEXT: [[TMP15:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK1-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], i8* [[TMP15]]) #[[ATTR4]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !18 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP20:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP18]], i8* [[TMP19]]) #[[ATTR4]], !noalias !18 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK1: .untied.jmp.1.i: -// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP17]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]] -// CHECK1-NEXT: store i32 1, i32* @a, align 4 -// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP17]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK1-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]], !noalias !18 +// CHECK1-NEXT: store i32 1, i32* @a, align 4, !noalias !18 +// CHECK1-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]], !noalias !18 +// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK1-NEXT: br label [[CLEANUP_I]] // CHECK1: cleanup.i: -// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK1: .omp_outlined..3.exit: // CHECK1-NEXT: ret i32 0 @@ -633,39 +633,39 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.4* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.5* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META33:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META40:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !42 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !42 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 -// CHECK1-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 -// CHECK1-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK1-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META21]]), !noalias !24 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP12]], %struct.anon.4** null, i64 0, metadata [[META26]]), !noalias !24 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store %struct.anon.4* [[TMP13]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !24 +// CHECK1-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK1-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK1-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK1-NEXT: ] // CHECK1: .untied.done..i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK1-NEXT: br label [[CLEANUP_I:%.*]] // CHECK1: .untied.jmp..i: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK1-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 -// CHECK1-NEXT: [[TMP15:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 -// CHECK1-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], i8* [[TMP15]]) #[[ATTR4]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK1-NEXT: [[TMP20:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP18]], i8* [[TMP19]]) #[[ATTR4]], !noalias !24 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__5_EXIT:%.*]] // CHECK1: .untied.jmp.1.i: -// CHECK1-NEXT: store i32 1, i32* @a, align 4 -// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK1-NEXT: store i32 1, i32* @a, align 4, !noalias !24 +// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK1-NEXT: br label [[CLEANUP_I]] // CHECK1: cleanup.i: -// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__5_EXIT]] // CHECK1: .omp_outlined..5.exit: // CHECK1-NEXT: ret i32 0 @@ -693,39 +693,39 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.6* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.7* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META43:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META46:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK1-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META27]]), !noalias !30 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META32:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP12]], %struct.anon.6** null, i64 0, metadata [[META32]]), !noalias !30 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !30 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !30 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !30 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !30 +// CHECK1-NEXT: store %struct.anon.6* [[TMP13]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !30 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !30 +// CHECK1-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !30 +// CHECK1-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK1-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK1-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK1-NEXT: ] // CHECK1: .untied.done..i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK1-NEXT: br label [[CLEANUP_I:%.*]] // CHECK1: .untied.jmp..i: -// CHECK1-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK1-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK1-NEXT: [[TMP15:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK1-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], i8* [[TMP15]]) #[[ATTR4]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK1-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !30 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !30 +// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !30 +// CHECK1-NEXT: [[TMP20:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP18]], i8* [[TMP19]]) #[[ATTR4]], !noalias !30 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__7_EXIT:%.*]] // CHECK1: .untied.jmp.1.i: -// CHECK1-NEXT: store i32 1, i32* @a, align 4 -// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK1-NEXT: store i32 1, i32* @a, align 4, !noalias !30 +// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK1-NEXT: br label [[CLEANUP_I]] // CHECK1: cleanup.i: -// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__7_EXIT]] // CHECK1: .omp_outlined..7.exit: // CHECK1-NEXT: ret i32 0 @@ -752,18 +752,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.8* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.9* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META53:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store %struct.anon.8* [[TMP8]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK1-NEXT: store i32 2, i32* @a, align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META33:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META33]]), !noalias !36 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8** null, i64 0, metadata [[META38:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.8* @llvm.noalias.p0s_struct.anon.8s.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8* [[TMP8]], i8* [[TMP12]], %struct.anon.8** null, i64 0, metadata [[META38]]), !noalias !36 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !36 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !36 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !36 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !36 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !36 +// CHECK1-NEXT: store %struct.anon.8* [[TMP13]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !36 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !36 +// CHECK1-NEXT: store i32 2, i32* @a, align 4, !noalias !36 // CHECK1-NEXT: ret i32 0 // // @@ -788,18 +788,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.10* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.11* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META63:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META66:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META68:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META70:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !72 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !72 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !72 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !72 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !72 -// CHECK1-NEXT: store %struct.anon.10* [[TMP8]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !72 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !72 -// CHECK1-NEXT: store i32 2, i32* @a, align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META39:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META39]]), !noalias !42 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10** null, i64 0, metadata [[META44:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.10* @llvm.noalias.p0s_struct.anon.10s.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10* [[TMP8]], i8* [[TMP12]], %struct.anon.10** null, i64 0, metadata [[META44]]), !noalias !42 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !42 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !42 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 +// CHECK1-NEXT: store %struct.anon.10* [[TMP13]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 +// CHECK1-NEXT: store i32 2, i32* @a, align 4, !noalias !42 // CHECK1-NEXT: ret i32 0 // // @@ -824,18 +824,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.12* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.13* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META73:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META76:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META78:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META80:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !82 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !82 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !82 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !82 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !82 -// CHECK1-NEXT: store %struct.anon.12* [[TMP8]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !82 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !82 -// CHECK1-NEXT: store i32 3, i32* @a, align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META45:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META45]]), !noalias !48 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12** null, i64 0, metadata [[META50:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.12* @llvm.noalias.p0s_struct.anon.12s.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12* [[TMP8]], i8* [[TMP12]], %struct.anon.12** null, i64 0, metadata [[META50]]), !noalias !48 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !48 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !48 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !48 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !48 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !48 +// CHECK1-NEXT: store %struct.anon.12* [[TMP13]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK1-NEXT: store i32 3, i32* @a, align 4, !noalias !48 // CHECK1-NEXT: ret i32 0 // // @@ -860,21 +860,21 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.14* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.15* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META83:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META86:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META88:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META90:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !92 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !92 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !92 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !92 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !92 -// CHECK1-NEXT: store %struct.anon.14* [[TMP8]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !92 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !92 -// CHECK1-NEXT: store i32 4, i32* @a, align 4 -// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_14:%.*]], %struct.anon.14* [[TMP10]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8 -// CHECK1-NEXT: store i32 5, i32* [[TMP12]], align 128 +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META51:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META51]]), !noalias !54 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14** null, i64 0, metadata [[META56:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.14* @llvm.noalias.p0s_struct.anon.14s.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14* [[TMP8]], i8* [[TMP12]], %struct.anon.14** null, i64 0, metadata [[META56]]), !noalias !54 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !54 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !54 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !54 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !54 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !54 +// CHECK1-NEXT: store %struct.anon.14* [[TMP13]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 +// CHECK1-NEXT: store i32 4, i32* @a, align 4, !noalias !54 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_14:%.*]], %struct.anon.14* [[TMP14]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32*, i32** [[TMP15]], align 8, !noalias !54 +// CHECK1-NEXT: store i32 5, i32* [[TMP16]], align 128, !noalias !54 // CHECK1-NEXT: ret i32 0 // // @@ -916,24 +916,28 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP3]], i32 0, i32 2 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.18* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META93:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META96:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META98:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META100:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !102 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !102 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !102 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !102 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !102 -// CHECK1-NEXT: store %struct.anon.17* [[TMP8]], %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !102 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon.17*, %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !102 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !102 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !102 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i32**)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !102 -// CHECK1-NEXT: store i32 4, i32* [[TMP16]], align 128 -// CHECK1-NEXT: store i32 4, i32* @a, align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META57:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META57]]), !noalias !60 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META64:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META64]]), !noalias !60 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META65:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META65]]), !noalias !60 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.17s.i64(%struct.anon.17** null, i64 0, metadata [[META66:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon.17* @llvm.noalias.p0s_struct.anon.17s.p0i8.p0p0s_struct.anon.17s.i64(%struct.anon.17* [[TMP8]], i8* [[TMP18]], %struct.anon.17** null, i64 0, metadata [[META66]]), !noalias !60 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !60 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !60 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !60 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !60 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !60 +// CHECK1-NEXT: store %struct.anon.17* [[TMP19]], %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !60 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon.17*, %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !60 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !60 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !60 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i32**)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]], !noalias !60 +// CHECK1-NEXT: [[TMP24:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !60 +// CHECK1-NEXT: store i32 4, i32* [[TMP24]], align 128, !noalias !60 +// CHECK1-NEXT: store i32 4, i32* @a, align 4, !noalias !60 // CHECK1-NEXT: ret i32 0 // // @@ -999,28 +1003,32 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_19]], %struct.kmp_task_t_with_privates.19* [[TMP3]], i32 0, i32 2 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t.20* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.19* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META103:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META106:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META108:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META110:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.20*, i32**, %struct.S**, %struct.S***)* @.omp_task_privates_map..20 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: store %struct.anon.16* [[TMP8]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i32**, %struct.S**, %struct.S***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR_I]], %struct.S*** [[DOTLOCAL_PTR_ADDR1_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP17:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP18:%.*]] = load %struct.S**, %struct.S*** [[DOTLOCAL_PTR_ADDR1_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP18]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4 -// CHECK1-NEXT: switch i32 [[TMP21]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META67:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META67]]), !noalias !70 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META74:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META74]]), !noalias !70 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META75:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.20*, i32**, %struct.S**, %struct.S***)* @.omp_task_privates_map..20 to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META75]]), !noalias !70 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16** null, i64 0, metadata [[META76:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon.16* @llvm.noalias.p0s_struct.anon.16s.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16* [[TMP8]], i8* [[TMP18]], %struct.anon.16** null, i64 0, metadata [[META76]]), !noalias !70 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: store %struct.anon.16* [[TMP19]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i32**, %struct.S**, %struct.S***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR_I]], %struct.S*** [[DOTLOCAL_PTR_ADDR1_I]]) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[TMP24:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP25:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP26:%.*]] = load %struct.S**, %struct.S*** [[DOTLOCAL_PTR_ADDR1_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP27:%.*]] = load %struct.S*, %struct.S** [[TMP26]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4, !noalias !70 +// CHECK1-NEXT: switch i32 [[TMP29]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK1-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK1-NEXT: i32 1, label [[DOTUNTIED_JMP_2_I:%.*]] // CHECK1-NEXT: i32 2, label [[DOTUNTIED_JMP_3_I:%.*]] @@ -1029,82 +1037,82 @@ // CHECK1-NEXT: i32 5, label [[DOTUNTIED_JMP_10_I:%.*]] // CHECK1-NEXT: ] // CHECK1: .untied.done..i: -// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK1-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK1-NEXT: br label [[CLEANUP_I:%.*]] // CHECK1: .untied.jmp..i: -// CHECK1-NEXT: [[TMP22:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: store i32 1, i32* [[TMP22]], align 4 -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP23]], i8* [[TMP24]]) #[[ATTR4]] +// CHECK1-NEXT: [[TMP30:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: store i32 1, i32* [[TMP30]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP33:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP31]], i8* [[TMP32]]) #[[ATTR4]], !noalias !70 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT:%.*]] // CHECK1: .untied.jmp.2.i: -// CHECK1-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP17]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[DOTS2__VOID_ADDR_I:%.*]] = call i8* @__kmpc_alloc(i32 [[TMP26]], i64 4, i8* inttoptr (i64 7 to i8*)) #[[ATTR4]] +// CHECK1-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP25]]) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[DOTS2__VOID_ADDR_I:%.*]] = call i8* @__kmpc_alloc(i32 [[TMP34]], i64 4, i8* inttoptr (i64 7 to i8*)) #[[ATTR4]], !noalias !70 // CHECK1-NEXT: [[DOTS2__ADDR_I:%.*]] = bitcast i8* [[DOTS2__VOID_ADDR_I]] to %struct.S* -// CHECK1-NEXT: store %struct.S* [[DOTS2__ADDR_I]], %struct.S** [[TMP18]], align 8 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: store i32 2, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP29:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP30:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP28]], i8* [[TMP29]]) #[[ATTR4]] +// CHECK1-NEXT: store %struct.S* [[DOTS2__ADDR_I]], %struct.S** [[TMP26]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: store i32 2, i32* [[TMP35]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP37:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP36]], i8* [[TMP37]]) #[[ATTR4]], !noalias !70 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK1: .untied.jmp.3.i: -// CHECK1-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP19]]) #[[ATTR4]] -// CHECK1-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 0 -// CHECK1-NEXT: store i32 0, i32* [[A_I]], align 4 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP32:%.*]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @[[GLOB1]], i32 [[TMP31]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates.18*)* @.omp_task_entry..19 to i32 (i32, i8*)*)) #[[ATTR4]] -// CHECK1-NEXT: [[TMP33:%.*]] = bitcast i8* [[TMP32]] to %struct.kmp_task_t_with_privates.18* -// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18:%.*]], %struct.kmp_task_t_with_privates.18* [[TMP33]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP33]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT__KMP_PRIVATES_T:%.*]], %struct..kmp_privates.t* [[TMP35]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP16]], align 128 -// CHECK1-NEXT: store i32 [[TMP37]], i32* [[TMP36]], align 128 -// CHECK1-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP39:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP38]], i8* [[TMP32]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP40:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: store i32 3, i32* [[TMP40]], align 4 -// CHECK1-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP43:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP41]], i8* [[TMP42]]) #[[ATTR4]] +// CHECK1-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP27]]) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP27]], i32 0, i32 0 +// CHECK1-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @[[GLOB1]], i32 [[TMP39]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates.18*)* @.omp_task_entry..19 to i32 (i32, i8*)*)) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to %struct.kmp_task_t_with_privates.18* +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18:%.*]], %struct.kmp_task_t_with_privates.18* [[TMP41]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP41]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT__KMP_PRIVATES_T:%.*]], %struct..kmp_privates.t* [[TMP43]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP45:%.*]] = load i32, i32* [[TMP24]], align 128, !noalias !70 +// CHECK1-NEXT: store i32 [[TMP45]], i32* [[TMP44]], align 128, !noalias !70 +// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP47:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP46]], i8* [[TMP40]]) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[TMP48:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: store i32 3, i32* [[TMP48]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP51:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP49]], i8* [[TMP50]]) #[[ATTR4]], !noalias !70 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK1: .untied.jmp.5.i: -// CHECK1-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP45:%.*]] = call i32 @__kmpc_omp_taskyield(%struct.ident_t* @[[GLOB1]], i32 [[TMP44]], i32 0) #[[ATTR4]] -// CHECK1-NEXT: [[TMP46:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: store i32 4, i32* [[TMP46]], align 4 -// CHECK1-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP48:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP49:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP47]], i8* [[TMP48]]) #[[ATTR4]] +// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP53:%.*]] = call i32 @__kmpc_omp_taskyield(%struct.ident_t* @[[GLOB1]], i32 [[TMP52]], i32 0) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[TMP54:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: store i32 4, i32* [[TMP54]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP56:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP57:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP55]], i8* [[TMP56]]) #[[ATTR4]], !noalias !70 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK1: .untied.jmp.7.i: -// CHECK1-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP50:%.*]] = bitcast %struct.S* [[TMP17]] to i8* -// CHECK1-NEXT: [[TMP51:%.*]] = bitcast %struct.S* [[REF_TMP_I]] to i8* -// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP50]], i8* align 4 [[TMP51]], i64 4, i1 false) #[[ATTR4]] -// CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[A9_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 0 -// CHECK1-NEXT: store i32 10, i32* [[A9_I]], align 4 -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP53:%.*]] = call i32 @__kmpc_omp_taskwait(%struct.ident_t* @[[GLOB1]], i32 [[TMP52]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP54:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: store i32 5, i32* [[TMP54]], align 4 -// CHECK1-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP56:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK1-NEXT: [[TMP57:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP55]], i8* [[TMP56]]) #[[ATTR4]] +// CHECK1-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[TMP58:%.*]] = bitcast %struct.S* [[TMP25]] to i8* +// CHECK1-NEXT: [[TMP59:%.*]] = bitcast %struct.S* [[REF_TMP_I]] to i8* +// CHECK1-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP58]], i8* align 4 [[TMP59]], i64 4, i1 false) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[A9_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP27]], i32 0, i32 0 +// CHECK1-NEXT: store i32 10, i32* [[A9_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP61:%.*]] = call i32 @__kmpc_omp_taskwait(%struct.ident_t* @[[GLOB1]], i32 [[TMP60]]) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: store i32 5, i32* [[TMP62]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP64:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK1-NEXT: [[TMP65:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP63]], i8* [[TMP64]]) #[[ATTR4]], !noalias !70 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK1: .untied.jmp.10.i: -// CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP19]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK1-NEXT: [[TMP59:%.*]] = bitcast %struct.S* [[TMP19]] to i8* -// CHECK1-NEXT: call void @__kmpc_free(i32 [[TMP58]], i8* [[TMP59]], i8* inttoptr (i64 7 to i8*)) #[[ATTR4]] -// CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP17]]) #[[ATTR4]] -// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP27]]) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: [[TMP66:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK1-NEXT: [[TMP67:%.*]] = bitcast %struct.S* [[TMP27]] to i8* +// CHECK1-NEXT: call void @__kmpc_free(i32 [[TMP66]], i8* [[TMP67]], i8* inttoptr (i64 7 to i8*)) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP25]]) #[[ATTR4]], !noalias !70 +// CHECK1-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK1-NEXT: br label [[CLEANUP_I]] // CHECK1: cleanup.i: -// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK1-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK1-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK1: .omp_outlined..17.exit: // CHECK1-NEXT: ret i32 0 @@ -1199,21 +1207,21 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.21* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.22* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META113:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META116:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META118:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META120:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !122 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !122 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !122 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !122 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !122 -// CHECK1-NEXT: store %struct.anon.21* [[TMP8]], %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !122 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.21*, %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !122 -// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_21:%.*]], %struct.anon.21* [[TMP10]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.S1*, %struct.S1** [[TMP11]], align 8 -// CHECK1-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP12]], i32 0, i32 0 -// CHECK1-NEXT: store i32 0, i32* [[A_I]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META77:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META77]]), !noalias !80 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.21s.i64(%struct.anon.21** null, i64 0, metadata [[META82:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.21* @llvm.noalias.p0s_struct.anon.21s.p0i8.p0p0s_struct.anon.21s.i64(%struct.anon.21* [[TMP8]], i8* [[TMP12]], %struct.anon.21** null, i64 0, metadata [[META82]]), !noalias !80 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !80 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !80 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !80 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !80 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !80 +// CHECK1-NEXT: store %struct.anon.21* [[TMP13]], %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !80 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.21*, %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !80 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_21:%.*]], %struct.anon.21* [[TMP14]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP16:%.*]] = load %struct.S1*, %struct.S1** [[TMP15]], align 8, !noalias !80 +// CHECK1-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP16]], i32 0, i32 0 +// CHECK1-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !80 // CHECK1-NEXT: ret i32 0 // // @@ -1309,30 +1317,34 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_24]], %struct.kmp_task_t_with_privates.24* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t.25* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.24* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META123:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META126:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META128:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META130:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !132 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !132 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !132 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.25*, double**)* @.omp_task_privates_map..26 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !132 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !132 -// CHECK1-NEXT: store %struct.anon.23* [[TMP8]], %struct.anon.23** [[__CONTEXT_ADDR_I]], align 8, !noalias !132 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon.23*, %struct.anon.23** [[__CONTEXT_ADDR_I]], align 8, !noalias !132 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !132 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !132 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, double**)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], double** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]] -// CHECK1-NEXT: [[TMP16:%.*]] = load double*, double** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !132 -// CHECK1-NEXT: [[TMP17:%.*]] = load double, double* [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_ANON_23:%.*]], %struct.anon.23* [[TMP12]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP19:%.*]] = load float*, float** [[TMP18]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load float, float* [[TMP19]], align 4 -// CHECK1-NEXT: [[CONV_I:%.*]] = fpext float [[TMP20]] to double -// CHECK1-NEXT: [[ADD_I:%.*]] = fadd double [[CONV_I]], [[TMP17]] +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META83:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META83]]), !noalias !86 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META90:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META90]]), !noalias !86 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META91:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.25*, double**)* @.omp_task_privates_map..26 to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META91]]), !noalias !86 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.23s.i64(%struct.anon.23** null, i64 0, metadata [[META92:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon.23* @llvm.noalias.p0s_struct.anon.23s.p0i8.p0p0s_struct.anon.23s.i64(%struct.anon.23* [[TMP8]], i8* [[TMP18]], %struct.anon.23** null, i64 0, metadata [[META92]]), !noalias !86 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !86 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !86 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !86 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !86 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !86 +// CHECK1-NEXT: store %struct.anon.23* [[TMP19]], %struct.anon.23** [[__CONTEXT_ADDR_I]], align 8, !noalias !86 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon.23*, %struct.anon.23** [[__CONTEXT_ADDR_I]], align 8, !noalias !86 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !86 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !86 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, double**)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], double** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]], !noalias !86 +// CHECK1-NEXT: [[TMP24:%.*]] = load double*, double** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !86 +// CHECK1-NEXT: [[TMP25:%.*]] = load double, double* [[TMP24]], align 8, !noalias !86 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_23:%.*]], %struct.anon.23* [[TMP20]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP27:%.*]] = load float*, float** [[TMP26]], align 8, !noalias !86 +// CHECK1-NEXT: [[TMP28:%.*]] = load float, float* [[TMP27]], align 4, !noalias !86 +// CHECK1-NEXT: [[CONV_I:%.*]] = fpext float [[TMP28]] to double +// CHECK1-NEXT: [[ADD_I:%.*]] = fadd double [[CONV_I]], [[TMP25]] // CHECK1-NEXT: [[CONV1_I:%.*]] = fptrunc double [[ADD_I]] to float -// CHECK1-NEXT: store float [[CONV1_I]], float* [[TMP19]], align 4 +// CHECK1-NEXT: store float [[CONV1_I]], float* [[TMP27]], align 4, !noalias !86 // CHECK1-NEXT: ret i32 0 // // @@ -1674,28 +1686,28 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i32 15, i32* @a, align 4 -// CHECK2-NEXT: [[TMP11:%.*]] = load i32, i32* @a, align 4 -// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP11]] to i8 -// CHECK2-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP10]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP13:%.*]] = load i8*, i8** [[TMP12]], align 8 -// CHECK2-NEXT: store i8 [[CONV_I]], i8* [[TMP13]], align 1 -// CHECK2-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP10]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP15:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP14]], align 8 -// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP15]], i64 0, i64 0 +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META8:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META8]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i32 15, i32* @a, align 4, !noalias !6 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32, i32* @a, align 4, !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP15]] to i8 +// CHECK2-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP14]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP17:%.*]] = load i8*, i8** [[TMP16]], align 8, !noalias !6 +// CHECK2-NEXT: store i8 [[CONV_I]], i8* [[TMP17]], align 1, !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP14]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP19:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP18]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP19]], i64 0, i64 0 // CHECK2-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[ARRAYIDX_I]], i32 0, i32 0 -// CHECK2-NEXT: store i32 10, i32* [[A_I]], align 4 +// CHECK2-NEXT: store i32 10, i32* [[A_I]], align 4, !noalias !6 // CHECK2-NEXT: ret i32 0 // // @@ -1720,23 +1732,23 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !22 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !22 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !22 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !22 -// CHECK2-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !22 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !22 -// CHECK2-NEXT: store i32 15, i32* @a, align 4 -// CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], %struct.anon.0* [[TMP10]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP12:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP11]], align 8 -// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP12]], i64 0, i64 1 +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META9]]), !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META14]]), !noalias !12 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 +// CHECK2-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 +// CHECK2-NEXT: store i32 15, i32* @a, align 4, !noalias !12 +// CHECK2-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], %struct.anon.0* [[TMP14]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP16:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP15]], align 8, !noalias !12 +// CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP16]], i64 0, i64 1 // CHECK2-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[ARRAYIDX_I]], i32 0, i32 0 -// CHECK2-NEXT: store i32 10, i32* [[A_I]], align 4 +// CHECK2-NEXT: store i32 10, i32* [[A_I]], align 4, !noalias !12 // CHECK2-NEXT: ret i32 0 // // @@ -1762,42 +1774,42 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.2* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.3* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK2-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP12]], %struct.anon.2** null, i64 0, metadata [[META20]]), !noalias !18 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store %struct.anon.2* [[TMP13]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !18 +// CHECK2-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK2-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK2-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK2-NEXT: ] // CHECK2: .untied.done..i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK2-NEXT: br label [[CLEANUP_I:%.*]] // CHECK2: .untied.jmp..i: -// CHECK2-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK2-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK2-NEXT: [[TMP15:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK2-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], i8* [[TMP15]]) #[[ATTR4]] +// CHECK2-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !18 +// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP20:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP18]], i8* [[TMP19]]) #[[ATTR4]], !noalias !18 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK2: .untied.jmp.1.i: -// CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK2-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP17]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]] -// CHECK2-NEXT: store i32 1, i32* @a, align 4 -// CHECK2-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP17]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]] -// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK2-NEXT: [[TMP21:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK2-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]], !noalias !18 +// CHECK2-NEXT: store i32 1, i32* @a, align 4, !noalias !18 +// CHECK2-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[TMP21]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]], !noalias !18 +// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK2-NEXT: br label [[CLEANUP_I]] // CHECK2: cleanup.i: -// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK2: .omp_outlined..3.exit: // CHECK2-NEXT: ret i32 0 @@ -1825,39 +1837,39 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.4* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.5* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META33:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META40:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !42 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !42 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 -// CHECK2-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 -// CHECK2-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK2-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META21]]), !noalias !24 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP12]], %struct.anon.4** null, i64 0, metadata [[META26]]), !noalias !24 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store %struct.anon.4* [[TMP13]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !24 +// CHECK2-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK2-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK2-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK2-NEXT: ] // CHECK2: .untied.done..i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK2-NEXT: br label [[CLEANUP_I:%.*]] // CHECK2: .untied.jmp..i: -// CHECK2-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK2-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK2-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 -// CHECK2-NEXT: [[TMP15:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 -// CHECK2-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], i8* [[TMP15]]) #[[ATTR4]] +// CHECK2-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK2-NEXT: [[TMP20:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP18]], i8* [[TMP19]]) #[[ATTR4]], !noalias !24 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__5_EXIT:%.*]] // CHECK2: .untied.jmp.1.i: -// CHECK2-NEXT: store i32 1, i32* @a, align 4 -// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK2-NEXT: store i32 1, i32* @a, align 4, !noalias !24 +// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK2-NEXT: br label [[CLEANUP_I]] // CHECK2: cleanup.i: -// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__5_EXIT]] // CHECK2: .omp_outlined..5.exit: // CHECK2-NEXT: ret i32 0 @@ -1885,39 +1897,39 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.6* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.7* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META43:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META46:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK2-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META27]]), !noalias !30 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META32:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP12]], %struct.anon.6** null, i64 0, metadata [[META32]]), !noalias !30 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !30 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !30 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !30 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !30 +// CHECK2-NEXT: store %struct.anon.6* [[TMP13]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !30 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !30 +// CHECK2-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK2-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !30 +// CHECK2-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK2-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK2-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK2-NEXT: ] // CHECK2: .untied.done..i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK2-NEXT: br label [[CLEANUP_I:%.*]] // CHECK2: .untied.jmp..i: -// CHECK2-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK2-NEXT: [[TMP14:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK2-NEXT: [[TMP15:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK2-NEXT: [[TMP16:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP14]], i8* [[TMP15]]) #[[ATTR4]] +// CHECK2-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK2-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !30 +// CHECK2-NEXT: [[TMP18:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !30 +// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !30 +// CHECK2-NEXT: [[TMP20:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP18]], i8* [[TMP19]]) #[[ATTR4]], !noalias !30 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__7_EXIT:%.*]] // CHECK2: .untied.jmp.1.i: -// CHECK2-NEXT: store i32 1, i32* @a, align 4 -// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK2-NEXT: store i32 1, i32* @a, align 4, !noalias !30 +// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK2-NEXT: br label [[CLEANUP_I]] // CHECK2: cleanup.i: -// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__7_EXIT]] // CHECK2: .omp_outlined..7.exit: // CHECK2-NEXT: ret i32 0 @@ -1944,18 +1956,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.8* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.9* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META53:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store %struct.anon.8* [[TMP8]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK2-NEXT: store i32 2, i32* @a, align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META33:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META33]]), !noalias !36 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8** null, i64 0, metadata [[META38:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.8* @llvm.noalias.p0s_struct.anon.8s.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8* [[TMP8]], i8* [[TMP12]], %struct.anon.8** null, i64 0, metadata [[META38]]), !noalias !36 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !36 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !36 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !36 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !36 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !36 +// CHECK2-NEXT: store %struct.anon.8* [[TMP13]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !36 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !36 +// CHECK2-NEXT: store i32 2, i32* @a, align 4, !noalias !36 // CHECK2-NEXT: ret i32 0 // // @@ -1980,18 +1992,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.10* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.11* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META63:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META66:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META68:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META70:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !72 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !72 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !72 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !72 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !72 -// CHECK2-NEXT: store %struct.anon.10* [[TMP8]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !72 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !72 -// CHECK2-NEXT: store i32 2, i32* @a, align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META39:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META39]]), !noalias !42 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10** null, i64 0, metadata [[META44:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.10* @llvm.noalias.p0s_struct.anon.10s.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10* [[TMP8]], i8* [[TMP12]], %struct.anon.10** null, i64 0, metadata [[META44]]), !noalias !42 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !42 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !42 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 +// CHECK2-NEXT: store %struct.anon.10* [[TMP13]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 +// CHECK2-NEXT: store i32 2, i32* @a, align 4, !noalias !42 // CHECK2-NEXT: ret i32 0 // // @@ -2016,18 +2028,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.12* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.13* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META73:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META76:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META78:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META80:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !82 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !82 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !82 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !82 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !82 -// CHECK2-NEXT: store %struct.anon.12* [[TMP8]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !82 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !82 -// CHECK2-NEXT: store i32 3, i32* @a, align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META45:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META45]]), !noalias !48 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12** null, i64 0, metadata [[META50:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.12* @llvm.noalias.p0s_struct.anon.12s.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12* [[TMP8]], i8* [[TMP12]], %struct.anon.12** null, i64 0, metadata [[META50]]), !noalias !48 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !48 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !48 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !48 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !48 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !48 +// CHECK2-NEXT: store %struct.anon.12* [[TMP13]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK2-NEXT: store i32 3, i32* @a, align 4, !noalias !48 // CHECK2-NEXT: ret i32 0 // // @@ -2052,21 +2064,21 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.14* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.15* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META83:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META86:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META88:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META90:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !92 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !92 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !92 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !92 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !92 -// CHECK2-NEXT: store %struct.anon.14* [[TMP8]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !92 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !92 -// CHECK2-NEXT: store i32 4, i32* @a, align 4 -// CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_14:%.*]], %struct.anon.14* [[TMP10]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8 -// CHECK2-NEXT: store i32 5, i32* [[TMP12]], align 128 +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META51:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META51]]), !noalias !54 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14** null, i64 0, metadata [[META56:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.14* @llvm.noalias.p0s_struct.anon.14s.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14* [[TMP8]], i8* [[TMP12]], %struct.anon.14** null, i64 0, metadata [[META56]]), !noalias !54 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !54 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !54 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !54 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !54 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !54 +// CHECK2-NEXT: store %struct.anon.14* [[TMP13]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 +// CHECK2-NEXT: store i32 4, i32* @a, align 4, !noalias !54 +// CHECK2-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_14:%.*]], %struct.anon.14* [[TMP14]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP16:%.*]] = load i32*, i32** [[TMP15]], align 8, !noalias !54 +// CHECK2-NEXT: store i32 5, i32* [[TMP16]], align 128, !noalias !54 // CHECK2-NEXT: ret i32 0 // // @@ -2108,24 +2120,28 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP3]], i32 0, i32 2 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.18* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META93:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META96:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META98:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META100:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !102 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !102 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !102 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !102 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !102 -// CHECK2-NEXT: store %struct.anon.17* [[TMP8]], %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !102 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon.17*, %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !102 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !102 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !102 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i32**)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !102 -// CHECK2-NEXT: store i32 4, i32* [[TMP16]], align 128 -// CHECK2-NEXT: store i32 4, i32* @a, align 4 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META57:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META57]]), !noalias !60 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META64:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META64]]), !noalias !60 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META65:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META65]]), !noalias !60 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.17s.i64(%struct.anon.17** null, i64 0, metadata [[META66:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon.17* @llvm.noalias.p0s_struct.anon.17s.p0i8.p0p0s_struct.anon.17s.i64(%struct.anon.17* [[TMP8]], i8* [[TMP18]], %struct.anon.17** null, i64 0, metadata [[META66]]), !noalias !60 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !60 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !60 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !60 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !60 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !60 +// CHECK2-NEXT: store %struct.anon.17* [[TMP19]], %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !60 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon.17*, %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !60 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !60 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !60 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i32**)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]], !noalias !60 +// CHECK2-NEXT: [[TMP24:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !60 +// CHECK2-NEXT: store i32 4, i32* [[TMP24]], align 128, !noalias !60 +// CHECK2-NEXT: store i32 4, i32* @a, align 4, !noalias !60 // CHECK2-NEXT: ret i32 0 // // @@ -2191,28 +2207,32 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_19]], %struct.kmp_task_t_with_privates.19* [[TMP3]], i32 0, i32 2 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t.20* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.19* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META103:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META106:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META108:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META110:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.20*, i32**, %struct.S**, %struct.S***)* @.omp_task_privates_map..20 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: store %struct.anon.16* [[TMP8]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i32**, %struct.S**, %struct.S***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR_I]], %struct.S*** [[DOTLOCAL_PTR_ADDR1_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP17:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP18:%.*]] = load %struct.S**, %struct.S*** [[DOTLOCAL_PTR_ADDR1_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP19:%.*]] = load %struct.S*, %struct.S** [[TMP18]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4 -// CHECK2-NEXT: switch i32 [[TMP21]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META67:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META67]]), !noalias !70 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META74:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META74]]), !noalias !70 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META75:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.20*, i32**, %struct.S**, %struct.S***)* @.omp_task_privates_map..20 to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META75]]), !noalias !70 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16** null, i64 0, metadata [[META76:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon.16* @llvm.noalias.p0s_struct.anon.16s.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16* [[TMP8]], i8* [[TMP18]], %struct.anon.16** null, i64 0, metadata [[META76]]), !noalias !70 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: store %struct.anon.16* [[TMP19]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i32**, %struct.S**, %struct.S***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR_I]], %struct.S*** [[DOTLOCAL_PTR_ADDR1_I]]) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[TMP24:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP25:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP26:%.*]] = load %struct.S**, %struct.S*** [[DOTLOCAL_PTR_ADDR1_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP27:%.*]] = load %struct.S*, %struct.S** [[TMP26]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP28]], align 4, !noalias !70 +// CHECK2-NEXT: switch i32 [[TMP29]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK2-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK2-NEXT: i32 1, label [[DOTUNTIED_JMP_2_I:%.*]] // CHECK2-NEXT: i32 2, label [[DOTUNTIED_JMP_3_I:%.*]] @@ -2221,82 +2241,82 @@ // CHECK2-NEXT: i32 5, label [[DOTUNTIED_JMP_10_I:%.*]] // CHECK2-NEXT: ] // CHECK2: .untied.done..i: -// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK2-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK2-NEXT: br label [[CLEANUP_I:%.*]] // CHECK2: .untied.jmp..i: -// CHECK2-NEXT: [[TMP22:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: store i32 1, i32* [[TMP22]], align 4 -// CHECK2-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP25:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP23]], i8* [[TMP24]]) #[[ATTR4]] +// CHECK2-NEXT: [[TMP30:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: store i32 1, i32* [[TMP30]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP33:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP31]], i8* [[TMP32]]) #[[ATTR4]], !noalias !70 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT:%.*]] // CHECK2: .untied.jmp.2.i: -// CHECK2-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP17]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP26:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[DOTS2__VOID_ADDR_I:%.*]] = call i8* @__kmpc_alloc(i32 [[TMP26]], i64 4, i8* inttoptr (i64 7 to i8*)) #[[ATTR4]] +// CHECK2-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP25]]) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[TMP34:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[DOTS2__VOID_ADDR_I:%.*]] = call i8* @__kmpc_alloc(i32 [[TMP34]], i64 4, i8* inttoptr (i64 7 to i8*)) #[[ATTR4]], !noalias !70 // CHECK2-NEXT: [[DOTS2__ADDR_I:%.*]] = bitcast i8* [[DOTS2__VOID_ADDR_I]] to %struct.S* -// CHECK2-NEXT: store %struct.S* [[DOTS2__ADDR_I]], %struct.S** [[TMP18]], align 8 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: store i32 2, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP29:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP30:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP28]], i8* [[TMP29]]) #[[ATTR4]] +// CHECK2-NEXT: store %struct.S* [[DOTS2__ADDR_I]], %struct.S** [[TMP26]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: store i32 2, i32* [[TMP35]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP37:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP38:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP36]], i8* [[TMP37]]) #[[ATTR4]], !noalias !70 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK2: .untied.jmp.3.i: -// CHECK2-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP19]]) #[[ATTR4]] -// CHECK2-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 0 -// CHECK2-NEXT: store i32 0, i32* [[A_I]], align 4 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP32:%.*]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @[[GLOB1]], i32 [[TMP31]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates.18*)* @.omp_task_entry..19 to i32 (i32, i8*)*)) #[[ATTR4]] -// CHECK2-NEXT: [[TMP33:%.*]] = bitcast i8* [[TMP32]] to %struct.kmp_task_t_with_privates.18* -// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18:%.*]], %struct.kmp_task_t_with_privates.18* [[TMP33]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP33]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT__KMP_PRIVATES_T:%.*]], %struct..kmp_privates.t* [[TMP35]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP16]], align 128 -// CHECK2-NEXT: store i32 [[TMP37]], i32* [[TMP36]], align 128 -// CHECK2-NEXT: [[TMP38:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP39:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP38]], i8* [[TMP32]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP40:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: store i32 3, i32* [[TMP40]], align 4 -// CHECK2-NEXT: [[TMP41:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP43:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP41]], i8* [[TMP42]]) #[[ATTR4]] +// CHECK2-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP27]]) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP27]], i32 0, i32 0 +// CHECK2-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP39:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @[[GLOB1]], i32 [[TMP39]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates.18*)* @.omp_task_entry..19 to i32 (i32, i8*)*)) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to %struct.kmp_task_t_with_privates.18* +// CHECK2-NEXT: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18:%.*]], %struct.kmp_task_t_with_privates.18* [[TMP41]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP43:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP41]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP44:%.*]] = getelementptr inbounds [[STRUCT__KMP_PRIVATES_T:%.*]], %struct..kmp_privates.t* [[TMP43]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP45:%.*]] = load i32, i32* [[TMP24]], align 128, !noalias !70 +// CHECK2-NEXT: store i32 [[TMP45]], i32* [[TMP44]], align 128, !noalias !70 +// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP47:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP46]], i8* [[TMP40]]) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[TMP48:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: store i32 3, i32* [[TMP48]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP51:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP49]], i8* [[TMP50]]) #[[ATTR4]], !noalias !70 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK2: .untied.jmp.5.i: -// CHECK2-NEXT: [[TMP44:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP45:%.*]] = call i32 @__kmpc_omp_taskyield(%struct.ident_t* @[[GLOB1]], i32 [[TMP44]], i32 0) #[[ATTR4]] -// CHECK2-NEXT: [[TMP46:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: store i32 4, i32* [[TMP46]], align 4 -// CHECK2-NEXT: [[TMP47:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP48:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP49:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP47]], i8* [[TMP48]]) #[[ATTR4]] +// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP53:%.*]] = call i32 @__kmpc_omp_taskyield(%struct.ident_t* @[[GLOB1]], i32 [[TMP52]], i32 0) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[TMP54:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: store i32 4, i32* [[TMP54]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP56:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP57:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP55]], i8* [[TMP56]]) #[[ATTR4]], !noalias !70 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK2: .untied.jmp.7.i: -// CHECK2-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP50:%.*]] = bitcast %struct.S* [[TMP17]] to i8* -// CHECK2-NEXT: [[TMP51:%.*]] = bitcast %struct.S* [[REF_TMP_I]] to i8* -// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP50]], i8* align 4 [[TMP51]], i64 4, i1 false) #[[ATTR4]] -// CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[A9_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP19]], i32 0, i32 0 -// CHECK2-NEXT: store i32 10, i32* [[A9_I]], align 4 -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP53:%.*]] = call i32 @__kmpc_omp_taskwait(%struct.ident_t* @[[GLOB1]], i32 [[TMP52]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP54:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: store i32 5, i32* [[TMP54]], align 4 -// CHECK2-NEXT: [[TMP55:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP56:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK2-NEXT: [[TMP57:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP55]], i8* [[TMP56]]) #[[ATTR4]] +// CHECK2-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[TMP58:%.*]] = bitcast %struct.S* [[TMP25]] to i8* +// CHECK2-NEXT: [[TMP59:%.*]] = bitcast %struct.S* [[REF_TMP_I]] to i8* +// CHECK2-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP58]], i8* align 4 [[TMP59]], i64 4, i1 false) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[A9_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[TMP27]], i32 0, i32 0 +// CHECK2-NEXT: store i32 10, i32* [[A9_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP60:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP61:%.*]] = call i32 @__kmpc_omp_taskwait(%struct.ident_t* @[[GLOB1]], i32 [[TMP60]]) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: store i32 5, i32* [[TMP62]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP63:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP64:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK2-NEXT: [[TMP65:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[TMP63]], i8* [[TMP64]]) #[[ATTR4]], !noalias !70 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK2: .untied.jmp.10.i: -// CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP19]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK2-NEXT: [[TMP59:%.*]] = bitcast %struct.S* [[TMP19]] to i8* -// CHECK2-NEXT: call void @__kmpc_free(i32 [[TMP58]], i8* [[TMP59]], i8* inttoptr (i64 7 to i8*)) #[[ATTR4]] -// CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP17]]) #[[ATTR4]] -// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP27]]) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: [[TMP66:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK2-NEXT: [[TMP67:%.*]] = bitcast %struct.S* [[TMP27]] to i8* +// CHECK2-NEXT: call void @__kmpc_free(i32 [[TMP66]], i8* [[TMP67]], i8* inttoptr (i64 7 to i8*)) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[TMP25]]) #[[ATTR4]], !noalias !70 +// CHECK2-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK2-NEXT: br label [[CLEANUP_I]] // CHECK2: cleanup.i: -// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK2-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK2-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK2: .omp_outlined..17.exit: // CHECK2-NEXT: ret i32 0 @@ -2391,21 +2411,21 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.21* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.22* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META113:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META116:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META118:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META120:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !122 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !122 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !122 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !122 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !122 -// CHECK2-NEXT: store %struct.anon.21* [[TMP8]], %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !122 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.21*, %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !122 -// CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_21:%.*]], %struct.anon.21* [[TMP10]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.S1*, %struct.S1** [[TMP11]], align 8 -// CHECK2-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP12]], i32 0, i32 0 -// CHECK2-NEXT: store i32 0, i32* [[A_I]], align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META77:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META77]]), !noalias !80 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.21s.i64(%struct.anon.21** null, i64 0, metadata [[META82:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.21* @llvm.noalias.p0s_struct.anon.21s.p0i8.p0p0s_struct.anon.21s.i64(%struct.anon.21* [[TMP8]], i8* [[TMP12]], %struct.anon.21** null, i64 0, metadata [[META82]]), !noalias !80 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !80 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !80 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !80 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !80 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !80 +// CHECK2-NEXT: store %struct.anon.21* [[TMP13]], %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !80 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.21*, %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !80 +// CHECK2-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_21:%.*]], %struct.anon.21* [[TMP14]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP16:%.*]] = load %struct.S1*, %struct.S1** [[TMP15]], align 8, !noalias !80 +// CHECK2-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP16]], i32 0, i32 0 +// CHECK2-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !80 // CHECK2-NEXT: ret i32 0 // // @@ -2501,30 +2521,34 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_24]], %struct.kmp_task_t_with_privates.24* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t.25* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.24* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META123:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META126:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META128:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META130:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !132 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !132 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !132 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.25*, double**)* @.omp_task_privates_map..26 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !132 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !132 -// CHECK2-NEXT: store %struct.anon.23* [[TMP8]], %struct.anon.23** [[__CONTEXT_ADDR_I]], align 8, !noalias !132 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon.23*, %struct.anon.23** [[__CONTEXT_ADDR_I]], align 8, !noalias !132 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !132 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !132 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, double**)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], double** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]] -// CHECK2-NEXT: [[TMP16:%.*]] = load double*, double** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !132 -// CHECK2-NEXT: [[TMP17:%.*]] = load double, double* [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_ANON_23:%.*]], %struct.anon.23* [[TMP12]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP19:%.*]] = load float*, float** [[TMP18]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load float, float* [[TMP19]], align 4 -// CHECK2-NEXT: [[CONV_I:%.*]] = fpext float [[TMP20]] to double -// CHECK2-NEXT: [[ADD_I:%.*]] = fadd double [[CONV_I]], [[TMP17]] +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META83:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META83]]), !noalias !86 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META90:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META90]]), !noalias !86 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META91:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.25*, double**)* @.omp_task_privates_map..26 to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META91]]), !noalias !86 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.23s.i64(%struct.anon.23** null, i64 0, metadata [[META92:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon.23* @llvm.noalias.p0s_struct.anon.23s.p0i8.p0p0s_struct.anon.23s.i64(%struct.anon.23* [[TMP8]], i8* [[TMP18]], %struct.anon.23** null, i64 0, metadata [[META92]]), !noalias !86 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !86 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !86 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !86 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !86 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !86 +// CHECK2-NEXT: store %struct.anon.23* [[TMP19]], %struct.anon.23** [[__CONTEXT_ADDR_I]], align 8, !noalias !86 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon.23*, %struct.anon.23** [[__CONTEXT_ADDR_I]], align 8, !noalias !86 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !86 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !86 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, double**)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], double** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]], !noalias !86 +// CHECK2-NEXT: [[TMP24:%.*]] = load double*, double** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !86 +// CHECK2-NEXT: [[TMP25:%.*]] = load double, double* [[TMP24]], align 8, !noalias !86 +// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON_23:%.*]], %struct.anon.23* [[TMP20]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP27:%.*]] = load float*, float** [[TMP26]], align 8, !noalias !86 +// CHECK2-NEXT: [[TMP28:%.*]] = load float, float* [[TMP27]], align 4, !noalias !86 +// CHECK2-NEXT: [[CONV_I:%.*]] = fpext float [[TMP28]] to double +// CHECK2-NEXT: [[ADD_I:%.*]] = fadd double [[CONV_I]], [[TMP25]] // CHECK2-NEXT: [[CONV1_I:%.*]] = fptrunc double [[ADD_I]] to float -// CHECK2-NEXT: store float [[CONV1_I]], float* [[TMP19]], align 4 +// CHECK2-NEXT: store float [[CONV1_I]], float* [[TMP27]], align 4, !noalias !86 // CHECK2-NEXT: ret i32 0 // // @@ -2885,28 +2909,28 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK3-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK3-NEXT: store i32 15, i32* @a, align 4 -// CHECK3-NEXT: [[TMP11:%.*]] = load i32, i32* @a, align 4 -// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP11]] to i8 -// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP10]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP13:%.*]] = load i8*, i8** [[TMP12]], align 8 -// CHECK3-NEXT: store i8 [[CONV_I]], i8* [[TMP13]], align 1 -// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP10]], i32 0, i32 1 -// CHECK3-NEXT: [[TMP15:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP14]], align 8 -// CHECK3-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP15]], i64 0, i64 0 +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META8:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META8]]), !noalias !6 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK3-NEXT: store i32 15, i32* @a, align 4, !noalias !6 +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, i32* @a, align 4, !noalias !6 +// CHECK3-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP15]] to i8 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP14]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP17:%.*]] = load i8*, i8** [[TMP16]], align 8, !noalias !6 +// CHECK3-NEXT: store i8 [[CONV_I]], i8* [[TMP17]], align 1, !noalias !6 +// CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP14]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP19:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP18]], align 8, !noalias !6 +// CHECK3-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP19]], i64 0, i64 0 // CHECK3-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[ARRAYIDX_I]], i32 0, i32 0 -// CHECK3-NEXT: store i32 10, i32* [[A_I]], align 4 +// CHECK3-NEXT: store i32 10, i32* [[A_I]], align 4, !noalias !6 // CHECK3-NEXT: ret i32 0 // // @@ -2931,23 +2955,23 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !22 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !22 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !22 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !22 -// CHECK3-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !22 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !22 -// CHECK3-NEXT: store i32 15, i32* @a, align 4 -// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], %struct.anon.0* [[TMP10]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP12:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP11]], align 8 -// CHECK3-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP12]], i64 0, i64 1 +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META9]]), !noalias !12 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META14]]), !noalias !12 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 +// CHECK3-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 +// CHECK3-NEXT: store i32 15, i32* @a, align 4, !noalias !12 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], %struct.anon.0* [[TMP14]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP16:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP15]], align 8, !noalias !12 +// CHECK3-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP16]], i64 0, i64 1 // CHECK3-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[ARRAYIDX_I]], i32 0, i32 0 -// CHECK3-NEXT: store i32 10, i32* [[A_I]], align 4 +// CHECK3-NEXT: store i32 10, i32* [[A_I]], align 4, !noalias !12 // CHECK3-NEXT: ret i32 0 // // @@ -2973,42 +2997,42 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.2* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.3* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK3-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK3-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK3-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP12]], %struct.anon.2** null, i64 0, metadata [[META20]]), !noalias !18 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK3-NEXT: store %struct.anon.2* [[TMP13]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK3-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !18 +// CHECK3-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK3-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK3-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK3-NEXT: ] // CHECK3: .untied.done..i: -// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK3-NEXT: br label [[CLEANUP_I:%.*]] // CHECK3: .untied.jmp..i: -// CHECK3-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK3-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB7]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP14]]) #[[ATTR4]] +// CHECK3-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK3-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !18 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB7]]) #[[ATTR4]], !noalias !18 +// CHECK3-NEXT: [[TMP18:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK3-NEXT: [[TMP19:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP18]]) #[[ATTR4]], !noalias !18 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK3: .untied.jmp.1.i: -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM2_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]] -// CHECK3-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2_I]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]] -// CHECK3-NEXT: store i32 1, i32* @a, align 4 -// CHECK3-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2_I]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]] -// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM2_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]], !noalias !18 +// CHECK3-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2_I]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]], !noalias !18 +// CHECK3-NEXT: store i32 1, i32* @a, align 4, !noalias !18 +// CHECK3-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2_I]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]], !noalias !18 +// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK3-NEXT: br label [[CLEANUP_I]] // CHECK3: cleanup.i: -// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK3: .omp_outlined..3.exit: // CHECK3-NEXT: ret i32 0 @@ -3036,39 +3060,39 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.4* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.5* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META33:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META40:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !42 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !42 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 -// CHECK3-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 -// CHECK3-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK3-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META21]]), !noalias !24 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP12]], %struct.anon.4** null, i64 0, metadata [[META26]]), !noalias !24 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK3-NEXT: store %struct.anon.4* [[TMP13]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK3-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !24 +// CHECK3-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK3-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK3-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK3-NEXT: ] // CHECK3: .untied.done..i: -// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK3-NEXT: br label [[CLEANUP_I:%.*]] // CHECK3: .untied.jmp..i: -// CHECK3-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK3-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB9]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 -// CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP14]]) #[[ATTR4]] +// CHECK3-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK3-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !24 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB9]]) #[[ATTR4]], !noalias !24 +// CHECK3-NEXT: [[TMP18:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK3-NEXT: [[TMP19:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP18]]) #[[ATTR4]], !noalias !24 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__5_EXIT:%.*]] // CHECK3: .untied.jmp.1.i: -// CHECK3-NEXT: store i32 1, i32* @a, align 4 -// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK3-NEXT: store i32 1, i32* @a, align 4, !noalias !24 +// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK3-NEXT: br label [[CLEANUP_I]] // CHECK3: cleanup.i: -// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__5_EXIT]] // CHECK3: .omp_outlined..5.exit: // CHECK3-NEXT: ret i32 0 @@ -3096,39 +3120,39 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.6* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.7* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META43:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META46:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !52 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !52 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK3-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK3-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK3-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK3-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META27]]), !noalias !30 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META32:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP12]], %struct.anon.6** null, i64 0, metadata [[META32]]), !noalias !30 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !30 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !30 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !30 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !30 +// CHECK3-NEXT: store %struct.anon.6* [[TMP13]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !30 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !30 +// CHECK3-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !30 +// CHECK3-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK3-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK3-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK3-NEXT: ] // CHECK3: .untied.done..i: -// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK3-NEXT: br label [[CLEANUP_I:%.*]] // CHECK3: .untied.jmp..i: -// CHECK3-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK3-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB11]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP14]]) #[[ATTR4]] +// CHECK3-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK3-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !30 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB11]]) #[[ATTR4]], !noalias !30 +// CHECK3-NEXT: [[TMP18:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !30 +// CHECK3-NEXT: [[TMP19:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP18]]) #[[ATTR4]], !noalias !30 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__7_EXIT:%.*]] // CHECK3: .untied.jmp.1.i: -// CHECK3-NEXT: store i32 1, i32* @a, align 4 -// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK3-NEXT: store i32 1, i32* @a, align 4, !noalias !30 +// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK3-NEXT: br label [[CLEANUP_I]] // CHECK3: cleanup.i: -// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__7_EXIT]] // CHECK3: .omp_outlined..7.exit: // CHECK3-NEXT: ret i32 0 @@ -3155,18 +3179,18 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.8* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.9* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META53:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 -// CHECK3-NEXT: store %struct.anon.8* [[TMP8]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK3-NEXT: store i32 2, i32* @a, align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META33:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META33]]), !noalias !36 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8** null, i64 0, metadata [[META38:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon.8* @llvm.noalias.p0s_struct.anon.8s.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8* [[TMP8]], i8* [[TMP12]], %struct.anon.8** null, i64 0, metadata [[META38]]), !noalias !36 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !36 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !36 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !36 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !36 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !36 +// CHECK3-NEXT: store %struct.anon.8* [[TMP13]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !36 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !36 +// CHECK3-NEXT: store i32 2, i32* @a, align 4, !noalias !36 // CHECK3-NEXT: ret i32 0 // // @@ -3191,18 +3215,18 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.10* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.11* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META63:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META66:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META68:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META70:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !72 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !72 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !72 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !72 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !72 -// CHECK3-NEXT: store %struct.anon.10* [[TMP8]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !72 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !72 -// CHECK3-NEXT: store i32 2, i32* @a, align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META39:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META39]]), !noalias !42 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10** null, i64 0, metadata [[META44:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon.10* @llvm.noalias.p0s_struct.anon.10s.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10* [[TMP8]], i8* [[TMP12]], %struct.anon.10** null, i64 0, metadata [[META44]]), !noalias !42 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !42 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !42 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 +// CHECK3-NEXT: store %struct.anon.10* [[TMP13]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 +// CHECK3-NEXT: store i32 2, i32* @a, align 4, !noalias !42 // CHECK3-NEXT: ret i32 0 // // @@ -3227,18 +3251,18 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.12* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.13* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META73:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META76:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META78:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META80:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !82 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !82 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !82 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !82 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !82 -// CHECK3-NEXT: store %struct.anon.12* [[TMP8]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !82 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !82 -// CHECK3-NEXT: store i32 3, i32* @a, align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META45:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META45]]), !noalias !48 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12** null, i64 0, metadata [[META50:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon.12* @llvm.noalias.p0s_struct.anon.12s.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12* [[TMP8]], i8* [[TMP12]], %struct.anon.12** null, i64 0, metadata [[META50]]), !noalias !48 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !48 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store %struct.anon.12* [[TMP13]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK3-NEXT: store i32 3, i32* @a, align 4, !noalias !48 // CHECK3-NEXT: ret i32 0 // // @@ -3263,21 +3287,21 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.14* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.15* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META83:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META86:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META88:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META90:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !92 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !92 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !92 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !92 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !92 -// CHECK3-NEXT: store %struct.anon.14* [[TMP8]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !92 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !92 -// CHECK3-NEXT: store i32 4, i32* @a, align 4 -// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_14:%.*]], %struct.anon.14* [[TMP10]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8 -// CHECK3-NEXT: store i32 5, i32* [[TMP12]], align 128 +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META51:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META51]]), !noalias !54 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14** null, i64 0, metadata [[META56:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon.14* @llvm.noalias.p0s_struct.anon.14s.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14* [[TMP8]], i8* [[TMP12]], %struct.anon.14** null, i64 0, metadata [[META56]]), !noalias !54 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !54 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !54 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !54 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !54 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !54 +// CHECK3-NEXT: store %struct.anon.14* [[TMP13]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 +// CHECK3-NEXT: store i32 4, i32* @a, align 4, !noalias !54 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_14:%.*]], %struct.anon.14* [[TMP14]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32*, i32** [[TMP15]], align 8, !noalias !54 +// CHECK3-NEXT: store i32 5, i32* [[TMP16]], align 128, !noalias !54 // CHECK3-NEXT: ret i32 0 // // @@ -3319,24 +3343,28 @@ // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP3]], i32 0, i32 2 // CHECK3-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK3-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.18* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META93:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META96:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META98:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META100:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !102 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !102 -// CHECK3-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !102 -// CHECK3-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !102 -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !102 -// CHECK3-NEXT: store %struct.anon.17* [[TMP8]], %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !102 -// CHECK3-NEXT: [[TMP12:%.*]] = load %struct.anon.17*, %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !102 -// CHECK3-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !102 -// CHECK3-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !102 -// CHECK3-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i32**)* -// CHECK3-NEXT: call void [[TMP15]](i8* [[TMP14]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP16:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !102 -// CHECK3-NEXT: store i32 4, i32* [[TMP16]], align 128 -// CHECK3-NEXT: store i32 4, i32* @a, align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META57:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META57]]), !noalias !60 +// CHECK3-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META64:![0-9]+]]) +// CHECK3-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META64]]), !noalias !60 +// CHECK3-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META65:![0-9]+]]) +// CHECK3-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META65]]), !noalias !60 +// CHECK3-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.17s.i64(%struct.anon.17** null, i64 0, metadata [[META66:![0-9]+]]) +// CHECK3-NEXT: [[TMP19:%.*]] = call %struct.anon.17* @llvm.noalias.p0s_struct.anon.17s.p0i8.p0p0s_struct.anon.17s.i64(%struct.anon.17* [[TMP8]], i8* [[TMP18]], %struct.anon.17** null, i64 0, metadata [[META66]]), !noalias !60 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !60 +// CHECK3-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !60 +// CHECK3-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !60 +// CHECK3-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !60 +// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !60 +// CHECK3-NEXT: store %struct.anon.17* [[TMP19]], %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !60 +// CHECK3-NEXT: [[TMP20:%.*]] = load %struct.anon.17*, %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !60 +// CHECK3-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !60 +// CHECK3-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !60 +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i32**)* +// CHECK3-NEXT: call void [[TMP23]](i8* [[TMP22]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]], !noalias !60 +// CHECK3-NEXT: [[TMP24:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !60 +// CHECK3-NEXT: store i32 4, i32* [[TMP24]], align 128, !noalias !60 +// CHECK3-NEXT: store i32 4, i32* @a, align 4, !noalias !60 // CHECK3-NEXT: ret i32 0 // // @@ -3404,27 +3432,31 @@ // CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_19]], %struct.kmp_task_t_with_privates.19* [[TMP3]], i32 0, i32 2 // CHECK3-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t.20* [[TMP9]] to i8* // CHECK3-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.19* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META103:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META106:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META108:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META110:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.20*, i32**, %struct.S**, %struct.S**)* @.omp_task_privates_map..20 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: store %struct.anon.16* [[TMP8]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP12:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i32**, %struct.S**, %struct.S**)* -// CHECK3-NEXT: call void [[TMP15]](i8* [[TMP14]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR1_I]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP16:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP17:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP18:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR1_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP19:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP20:%.*]] = load i32, i32* [[TMP19]], align 4 -// CHECK3-NEXT: switch i32 [[TMP20]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META67:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META67]]), !noalias !70 +// CHECK3-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META74:![0-9]+]]) +// CHECK3-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META74]]), !noalias !70 +// CHECK3-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META75:![0-9]+]]) +// CHECK3-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.20*, i32**, %struct.S**, %struct.S**)* @.omp_task_privates_map..20 to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META75]]), !noalias !70 +// CHECK3-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16** null, i64 0, metadata [[META76:![0-9]+]]) +// CHECK3-NEXT: [[TMP19:%.*]] = call %struct.anon.16* @llvm.noalias.p0s_struct.anon.16s.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16* [[TMP8]], i8* [[TMP18]], %struct.anon.16** null, i64 0, metadata [[META76]]), !noalias !70 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK3-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: store %struct.anon.16* [[TMP19]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP20:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i32**, %struct.S**, %struct.S**)* +// CHECK3-NEXT: call void [[TMP23]](i8* [[TMP22]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR1_I]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP24:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP25:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP26:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR1_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4, !noalias !70 +// CHECK3-NEXT: switch i32 [[TMP28]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK3-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK3-NEXT: i32 1, label [[DOTUNTIED_JMP_2_I:%.*]] // CHECK3-NEXT: i32 2, label [[DOTUNTIED_JMP_6_I:%.*]] @@ -3432,68 +3464,68 @@ // CHECK3-NEXT: i32 4, label [[DOTUNTIED_JMP_15_I:%.*]] // CHECK3-NEXT: ] // CHECK3: .untied.done..i: -// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK3-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK3-NEXT: br label [[CLEANUP_I:%.*]] // CHECK3: .untied.jmp..i: -// CHECK3-NEXT: [[TMP21:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: store i32 1, i32* [[TMP21]], align 4 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP23:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP22]]) #[[ATTR4]] +// CHECK3-NEXT: [[TMP29:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: store i32 1, i32* [[TMP29]], align 4, !noalias !70 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP30:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP31:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP30]]) #[[ATTR4]], !noalias !70 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT:%.*]] // CHECK3: .untied.jmp.2.i: -// CHECK3-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S1_I]]) #[[ATTR4]] -// CHECK3-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S2_I]]) #[[ATTR4]] +// CHECK3-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S1_I]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S2_I]]) #[[ATTR4]], !noalias !70 // CHECK3-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S2_I]], i32 0, i32 0 -// CHECK3-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !112 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM3_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB23:[0-9]+]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP24:%.*]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3_I]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates.18*)* @.omp_task_entry..19 to i32 (i32, i8*)*)) #[[ATTR4]] -// CHECK3-NEXT: [[TMP25:%.*]] = bitcast i8* [[TMP24]] to %struct.kmp_task_t_with_privates.18* -// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18:%.*]], %struct.kmp_task_t_with_privates.18* [[TMP25]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP25]], i32 0, i32 2 -// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT__KMP_PRIVATES_T:%.*]], %struct..kmp_privates.t* [[TMP27]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP16]], align 128 -// CHECK3-NEXT: store i32 [[TMP29]], i32* [[TMP28]], align 128 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM4_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB23]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP30:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM4_I]], i8* [[TMP24]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP31:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: store i32 2, i32* [[TMP31]], align 4 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM5_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP32:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP33:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM5_I]], i8* [[TMP32]]) #[[ATTR4]] +// CHECK3-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !70 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM3_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB23:[0-9]+]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP32:%.*]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3_I]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates.18*)* @.omp_task_entry..19 to i32 (i32, i8*)*)) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP33:%.*]] = bitcast i8* [[TMP32]] to %struct.kmp_task_t_with_privates.18* +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18:%.*]], %struct.kmp_task_t_with_privates.18* [[TMP33]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP33]], i32 0, i32 2 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT__KMP_PRIVATES_T:%.*]], %struct..kmp_privates.t* [[TMP35]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP24]], align 128, !noalias !70 +// CHECK3-NEXT: store i32 [[TMP37]], i32* [[TMP36]], align 128, !noalias !70 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM4_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB23]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP38:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM4_I]], i8* [[TMP32]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP39:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: store i32 2, i32* [[TMP39]], align 4, !noalias !70 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM5_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP40:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP41:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM5_I]], i8* [[TMP40]]) #[[ATTR4]], !noalias !70 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK3: .untied.jmp.6.i: -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM8_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP34:%.*]] = call i32 @__kmpc_omp_taskyield(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM8_I]], i32 0) #[[ATTR4]] -// CHECK3-NEXT: [[TMP35:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: store i32 3, i32* [[TMP35]], align 4 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM9_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP37:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM9_I]], i8* [[TMP36]]) #[[ATTR4]] +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM8_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP42:%.*]] = call i32 @__kmpc_omp_taskyield(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM8_I]], i32 0) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP43:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: store i32 3, i32* [[TMP43]], align 4, !noalias !70 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM9_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP44:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP45:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM9_I]], i8* [[TMP44]]) #[[ATTR4]], !noalias !70 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK3: .untied.jmp.10.i: -// CHECK3-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP38:%.*]] = bitcast %struct.S* [[S1_I]] to i8* -// CHECK3-NEXT: [[TMP39:%.*]] = bitcast %struct.S* [[REF_TMP_I]] to i8* -// CHECK3-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP38]], i8* align 4 [[TMP39]], i64 4, i1 false) #[[ATTR4]], !noalias !112 -// CHECK3-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]] +// CHECK3-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP46:%.*]] = bitcast %struct.S* [[S1_I]] to i8* +// CHECK3-NEXT: [[TMP47:%.*]] = bitcast %struct.S* [[REF_TMP_I]] to i8* +// CHECK3-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 4, i1 false) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]], !noalias !70 // CHECK3-NEXT: [[A12_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S2_I]], i32 0, i32 0 -// CHECK3-NEXT: store i32 10, i32* [[A12_I]], align 4, !noalias !112 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM13_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP40:%.*]] = call i32 @__kmpc_omp_taskwait(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM13_I]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: store i32 4, i32* [[TMP41]], align 4 -// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM14_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]] -// CHECK3-NEXT: [[TMP42:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK3-NEXT: [[TMP43:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM14_I]], i8* [[TMP42]]) #[[ATTR4]] +// CHECK3-NEXT: store i32 10, i32* [[A12_I]], align 4, !noalias !70 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM13_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP48:%.*]] = call i32 @__kmpc_omp_taskwait(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM13_I]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP49:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: store i32 4, i32* [[TMP49]], align 4, !noalias !70 +// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM14_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: [[TMP50:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK3-NEXT: [[TMP51:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM14_I]], i8* [[TMP50]]) #[[ATTR4]], !noalias !70 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK3: .untied.jmp.15.i: -// CHECK3-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S2_I]]) #[[ATTR4]] -// CHECK3-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S1_I]]) #[[ATTR4]] -// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK3-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S2_I]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S1_I]]) #[[ATTR4]], !noalias !70 +// CHECK3-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK3-NEXT: br label [[CLEANUP_I]] // CHECK3: cleanup.i: -// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK3-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK3-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK3: .omp_outlined..17.exit: // CHECK3-NEXT: ret i32 0 @@ -3589,21 +3621,21 @@ // CHECK3-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK3-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.21* // CHECK3-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.22* [[TMP3]] to i8* -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META113:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META116:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META118:![0-9]+]]) -// CHECK3-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META120:![0-9]+]]) -// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !122 -// CHECK3-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !122 -// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !122 -// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !122 -// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !122 -// CHECK3-NEXT: store %struct.anon.21* [[TMP8]], %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !122 -// CHECK3-NEXT: [[TMP10:%.*]] = load %struct.anon.21*, %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !122 -// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_21:%.*]], %struct.anon.21* [[TMP10]], i32 0, i32 0 -// CHECK3-NEXT: [[TMP12:%.*]] = load %struct.S1*, %struct.S1** [[TMP11]], align 8 -// CHECK3-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP12]], i32 0, i32 0 -// CHECK3-NEXT: store i32 0, i32* [[A_I]], align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META77:![0-9]+]]) +// CHECK3-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META77]]), !noalias !80 +// CHECK3-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.21s.i64(%struct.anon.21** null, i64 0, metadata [[META82:![0-9]+]]) +// CHECK3-NEXT: [[TMP13:%.*]] = call %struct.anon.21* @llvm.noalias.p0s_struct.anon.21s.p0i8.p0p0s_struct.anon.21s.i64(%struct.anon.21* [[TMP8]], i8* [[TMP12]], %struct.anon.21** null, i64 0, metadata [[META82]]), !noalias !80 +// CHECK3-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !80 +// CHECK3-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !80 +// CHECK3-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !80 +// CHECK3-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !80 +// CHECK3-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !80 +// CHECK3-NEXT: store %struct.anon.21* [[TMP13]], %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !80 +// CHECK3-NEXT: [[TMP14:%.*]] = load %struct.anon.21*, %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !80 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_21:%.*]], %struct.anon.21* [[TMP14]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP16:%.*]] = load %struct.S1*, %struct.S1** [[TMP15]], align 8, !noalias !80 +// CHECK3-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP16]], i32 0, i32 0 +// CHECK3-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !80 // CHECK3-NEXT: ret i32 0 // // @@ -3964,28 +3996,28 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK4-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK4-NEXT: store i32 15, i32* @a, align 4 -// CHECK4-NEXT: [[TMP11:%.*]] = load i32, i32* @a, align 4 -// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP11]] to i8 -// CHECK4-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP10]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP13:%.*]] = load i8*, i8** [[TMP12]], align 8 -// CHECK4-NEXT: store i8 [[CONV_I]], i8* [[TMP13]], align 1 -// CHECK4-NEXT: [[TMP14:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP10]], i32 0, i32 1 -// CHECK4-NEXT: [[TMP15:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP14]], align 8 -// CHECK4-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP15]], i64 0, i64 0 +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META8:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META8]]), !noalias !6 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK4-NEXT: store i32 15, i32* @a, align 4, !noalias !6 +// CHECK4-NEXT: [[TMP15:%.*]] = load i32, i32* @a, align 4, !noalias !6 +// CHECK4-NEXT: [[CONV_I:%.*]] = trunc i32 [[TMP15]] to i8 +// CHECK4-NEXT: [[TMP16:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP14]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP17:%.*]] = load i8*, i8** [[TMP16]], align 8, !noalias !6 +// CHECK4-NEXT: store i8 [[CONV_I]], i8* [[TMP17]], align 1, !noalias !6 +// CHECK4-NEXT: [[TMP18:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP14]], i32 0, i32 1 +// CHECK4-NEXT: [[TMP19:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP18]], align 8, !noalias !6 +// CHECK4-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP19]], i64 0, i64 0 // CHECK4-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[ARRAYIDX_I]], i32 0, i32 0 -// CHECK4-NEXT: store i32 10, i32* [[A_I]], align 4 +// CHECK4-NEXT: store i32 10, i32* [[A_I]], align 4, !noalias !6 // CHECK4-NEXT: ret i32 0 // // @@ -4010,23 +4042,23 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !22 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !22 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !22 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !22 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !22 -// CHECK4-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !22 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !22 -// CHECK4-NEXT: store i32 15, i32* @a, align 4 -// CHECK4-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], %struct.anon.0* [[TMP10]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP12:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP11]], align 8 -// CHECK4-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP12]], i64 0, i64 1 +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META9:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META9]]), !noalias !12 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META14]]), !noalias !12 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 +// CHECK4-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 +// CHECK4-NEXT: store i32 15, i32* @a, align 4, !noalias !12 +// CHECK4-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_0:%.*]], %struct.anon.0* [[TMP14]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP16:%.*]] = load [2 x %struct.S]*, [2 x %struct.S]** [[TMP15]], align 8, !noalias !12 +// CHECK4-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TMP16]], i64 0, i64 1 // CHECK4-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], %struct.S* [[ARRAYIDX_I]], i32 0, i32 0 -// CHECK4-NEXT: store i32 10, i32* [[A_I]], align 4 +// CHECK4-NEXT: store i32 10, i32* [[A_I]], align 4, !noalias !12 // CHECK4-NEXT: ret i32 0 // // @@ -4052,42 +4084,42 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.2* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.3* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META23:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META26:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK4-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 -// CHECK4-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK4-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK4-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP12]], %struct.anon.2** null, i64 0, metadata [[META20]]), !noalias !18 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK4-NEXT: store %struct.anon.2* [[TMP13]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK4-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK4-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !18 +// CHECK4-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK4-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK4-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK4-NEXT: ] // CHECK4: .untied.done..i: -// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK4-NEXT: br label [[CLEANUP_I:%.*]] // CHECK4: .untied.jmp..i: -// CHECK4-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 -// CHECK4-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB7]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 -// CHECK4-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP14]]) #[[ATTR4]] +// CHECK4-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK4-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !18 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB7]]) #[[ATTR4]], !noalias !18 +// CHECK4-NEXT: [[TMP18:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK4-NEXT: [[TMP19:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP18]]) #[[ATTR4]], !noalias !18 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT:%.*]] // CHECK4: .untied.jmp.1.i: -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM2_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]] -// CHECK4-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2_I]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]] -// CHECK4-NEXT: store i32 1, i32* @a, align 4 -// CHECK4-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2_I]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]] -// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM2_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]], !noalias !18 +// CHECK4-NEXT: call void @__kmpc_critical(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2_I]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]], !noalias !18 +// CHECK4-NEXT: store i32 1, i32* @a, align 4, !noalias !18 +// CHECK4-NEXT: call void @__kmpc_end_critical(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM2_I]], [8 x i32]* @.gomp_critical_user_.var) #[[ATTR4]], !noalias !18 +// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK4-NEXT: br label [[CLEANUP_I]] // CHECK4: cleanup.i: -// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !32 +// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !18 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__3_EXIT]] // CHECK4: .omp_outlined..3.exit: // CHECK4-NEXT: ret i32 0 @@ -4115,39 +4147,39 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.4* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.5* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META33:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META36:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META40:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !42 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !42 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 -// CHECK4-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 -// CHECK4-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK4-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK4-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META21:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META21]]), !noalias !24 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META26:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP12]], %struct.anon.4** null, i64 0, metadata [[META26]]), !noalias !24 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK4-NEXT: store %struct.anon.4* [[TMP13]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 +// CHECK4-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK4-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !24 +// CHECK4-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK4-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK4-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK4-NEXT: ] // CHECK4: .untied.done..i: -// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK4-NEXT: br label [[CLEANUP_I:%.*]] // CHECK4: .untied.jmp..i: -// CHECK4-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 -// CHECK4-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB9]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 -// CHECK4-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP14]]) #[[ATTR4]] +// CHECK4-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 +// CHECK4-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !24 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB9]]) #[[ATTR4]], !noalias !24 +// CHECK4-NEXT: [[TMP18:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 +// CHECK4-NEXT: [[TMP19:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP18]]) #[[ATTR4]], !noalias !24 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__5_EXIT:%.*]] // CHECK4: .untied.jmp.1.i: -// CHECK4-NEXT: store i32 1, i32* @a, align 4 -// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK4-NEXT: store i32 1, i32* @a, align 4, !noalias !24 +// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK4-NEXT: br label [[CLEANUP_I]] // CHECK4: cleanup.i: -// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !42 +// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !24 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__5_EXIT]] // CHECK4: .omp_outlined..5.exit: // CHECK4-NEXT: ret i32 0 @@ -4175,39 +4207,39 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.6* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.7* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META43:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META46:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !52 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !52 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !52 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK4-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !52 -// CHECK4-NEXT: [[TMP11:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK4-NEXT: [[TMP12:%.*]] = load i32, i32* [[TMP11]], align 4 -// CHECK4-NEXT: switch i32 [[TMP12]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META27:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META27]]), !noalias !30 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META32:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP12]], %struct.anon.6** null, i64 0, metadata [[META32]]), !noalias !30 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !30 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !30 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !30 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !30 +// CHECK4-NEXT: store %struct.anon.6* [[TMP13]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !30 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !30 +// CHECK4-NEXT: [[TMP15:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK4-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP15]], align 4, !noalias !30 +// CHECK4-NEXT: switch i32 [[TMP16]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK4-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK4-NEXT: i32 1, label [[DOTUNTIED_JMP_1_I:%.*]] // CHECK4-NEXT: ] // CHECK4: .untied.done..i: -// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK4-NEXT: br label [[CLEANUP_I:%.*]] // CHECK4: .untied.jmp..i: -// CHECK4-NEXT: [[TMP13:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !52 -// CHECK4-NEXT: store i32 1, i32* [[TMP13]], align 4 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB11]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !52 -// CHECK4-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP14]]) #[[ATTR4]] +// CHECK4-NEXT: [[TMP17:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !30 +// CHECK4-NEXT: store i32 1, i32* [[TMP17]], align 4, !noalias !30 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB11]]) #[[ATTR4]], !noalias !30 +// CHECK4-NEXT: [[TMP18:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !30 +// CHECK4-NEXT: [[TMP19:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP18]]) #[[ATTR4]], !noalias !30 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__7_EXIT:%.*]] // CHECK4: .untied.jmp.1.i: -// CHECK4-NEXT: store i32 1, i32* @a, align 4 -// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK4-NEXT: store i32 1, i32* @a, align 4, !noalias !30 +// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK4-NEXT: br label [[CLEANUP_I]] // CHECK4: cleanup.i: -// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !52 +// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !30 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__7_EXIT]] // CHECK4: .omp_outlined..7.exit: // CHECK4-NEXT: ret i32 0 @@ -4234,18 +4266,18 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.8* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.9* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META53:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META56:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 -// CHECK4-NEXT: store %struct.anon.8* [[TMP8]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 -// CHECK4-NEXT: store i32 2, i32* @a, align 4 +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META33:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META33]]), !noalias !36 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8** null, i64 0, metadata [[META38:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon.8* @llvm.noalias.p0s_struct.anon.8s.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8* [[TMP8]], i8* [[TMP12]], %struct.anon.8** null, i64 0, metadata [[META38]]), !noalias !36 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !36 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !36 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !36 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !36 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !36 +// CHECK4-NEXT: store %struct.anon.8* [[TMP13]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !36 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !36 +// CHECK4-NEXT: store i32 2, i32* @a, align 4, !noalias !36 // CHECK4-NEXT: ret i32 0 // // @@ -4270,18 +4302,18 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.10* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.11* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META63:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META66:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META68:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META70:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !72 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !72 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !72 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !72 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !72 -// CHECK4-NEXT: store %struct.anon.10* [[TMP8]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !72 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !72 -// CHECK4-NEXT: store i32 2, i32* @a, align 4 +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META39:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META39]]), !noalias !42 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10** null, i64 0, metadata [[META44:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon.10* @llvm.noalias.p0s_struct.anon.10s.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10* [[TMP8]], i8* [[TMP12]], %struct.anon.10** null, i64 0, metadata [[META44]]), !noalias !42 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !42 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !42 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !42 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !42 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !42 +// CHECK4-NEXT: store %struct.anon.10* [[TMP13]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !42 +// CHECK4-NEXT: store i32 2, i32* @a, align 4, !noalias !42 // CHECK4-NEXT: ret i32 0 // // @@ -4306,18 +4338,18 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.12* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.13* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META73:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META76:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META78:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META80:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !82 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !82 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !82 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !82 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !82 -// CHECK4-NEXT: store %struct.anon.12* [[TMP8]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !82 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !82 -// CHECK4-NEXT: store i32 3, i32* @a, align 4 +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META45:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META45]]), !noalias !48 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12** null, i64 0, metadata [[META50:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon.12* @llvm.noalias.p0s_struct.anon.12s.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12* [[TMP8]], i8* [[TMP12]], %struct.anon.12** null, i64 0, metadata [[META50]]), !noalias !48 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !48 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store %struct.anon.12* [[TMP13]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !48 +// CHECK4-NEXT: store i32 3, i32* @a, align 4, !noalias !48 // CHECK4-NEXT: ret i32 0 // // @@ -4342,21 +4374,21 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.14* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.15* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META83:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META86:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META88:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META90:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !92 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !92 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !92 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !92 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !92 -// CHECK4-NEXT: store %struct.anon.14* [[TMP8]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !92 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !92 -// CHECK4-NEXT: store i32 4, i32* @a, align 4 -// CHECK4-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_14:%.*]], %struct.anon.14* [[TMP10]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8 -// CHECK4-NEXT: store i32 5, i32* [[TMP12]], align 128 +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META51:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META51]]), !noalias !54 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14** null, i64 0, metadata [[META56:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon.14* @llvm.noalias.p0s_struct.anon.14s.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14* [[TMP8]], i8* [[TMP12]], %struct.anon.14** null, i64 0, metadata [[META56]]), !noalias !54 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !54 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !54 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !54 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !54 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !54 +// CHECK4-NEXT: store %struct.anon.14* [[TMP13]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 +// CHECK4-NEXT: store i32 4, i32* @a, align 4, !noalias !54 +// CHECK4-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_14:%.*]], %struct.anon.14* [[TMP14]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP16:%.*]] = load i32*, i32** [[TMP15]], align 8, !noalias !54 +// CHECK4-NEXT: store i32 5, i32* [[TMP16]], align 128, !noalias !54 // CHECK4-NEXT: ret i32 0 // // @@ -4398,24 +4430,28 @@ // CHECK4-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP3]], i32 0, i32 2 // CHECK4-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK4-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.18* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META93:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META96:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META98:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META100:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !102 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !102 -// CHECK4-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !102 -// CHECK4-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !102 -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !102 -// CHECK4-NEXT: store %struct.anon.17* [[TMP8]], %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !102 -// CHECK4-NEXT: [[TMP12:%.*]] = load %struct.anon.17*, %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !102 -// CHECK4-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !102 -// CHECK4-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !102 -// CHECK4-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i32**)* -// CHECK4-NEXT: call void [[TMP15]](i8* [[TMP14]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP16:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !102 -// CHECK4-NEXT: store i32 4, i32* [[TMP16]], align 128 -// CHECK4-NEXT: store i32 4, i32* @a, align 4 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META57:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META57]]), !noalias !60 +// CHECK4-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META64:![0-9]+]]) +// CHECK4-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META64]]), !noalias !60 +// CHECK4-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META65:![0-9]+]]) +// CHECK4-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i32**)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META65]]), !noalias !60 +// CHECK4-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.17s.i64(%struct.anon.17** null, i64 0, metadata [[META66:![0-9]+]]) +// CHECK4-NEXT: [[TMP19:%.*]] = call %struct.anon.17* @llvm.noalias.p0s_struct.anon.17s.p0i8.p0p0s_struct.anon.17s.i64(%struct.anon.17* [[TMP8]], i8* [[TMP18]], %struct.anon.17** null, i64 0, metadata [[META66]]), !noalias !60 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !60 +// CHECK4-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !60 +// CHECK4-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !60 +// CHECK4-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !60 +// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !60 +// CHECK4-NEXT: store %struct.anon.17* [[TMP19]], %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !60 +// CHECK4-NEXT: [[TMP20:%.*]] = load %struct.anon.17*, %struct.anon.17** [[__CONTEXT_ADDR_I]], align 8, !noalias !60 +// CHECK4-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !60 +// CHECK4-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !60 +// CHECK4-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i32**)* +// CHECK4-NEXT: call void [[TMP23]](i8* [[TMP22]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR4]], !noalias !60 +// CHECK4-NEXT: [[TMP24:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !60 +// CHECK4-NEXT: store i32 4, i32* [[TMP24]], align 128, !noalias !60 +// CHECK4-NEXT: store i32 4, i32* @a, align 4, !noalias !60 // CHECK4-NEXT: ret i32 0 // // @@ -4483,27 +4519,31 @@ // CHECK4-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_19]], %struct.kmp_task_t_with_privates.19* [[TMP3]], i32 0, i32 2 // CHECK4-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t.20* [[TMP9]] to i8* // CHECK4-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates.19* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META103:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META106:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META108:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META110:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !112 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.20*, i32**, %struct.S**, %struct.S**)* @.omp_task_privates_map..20 to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: store %struct.anon.16* [[TMP8]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP12:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i32**, %struct.S**, %struct.S**)* -// CHECK4-NEXT: call void [[TMP15]](i8* [[TMP14]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR1_I]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP16:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP17:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP18:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR1_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP19:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP20:%.*]] = load i32, i32* [[TMP19]], align 4 -// CHECK4-NEXT: switch i32 [[TMP20]], label [[DOTUNTIED_DONE__I:%.*]] [ +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META67:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META67]]), !noalias !70 +// CHECK4-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META74:![0-9]+]]) +// CHECK4-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META74]]), !noalias !70 +// CHECK4-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META75:![0-9]+]]) +// CHECK4-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t.20*, i32**, %struct.S**, %struct.S**)* @.omp_task_privates_map..20 to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META75]]), !noalias !70 +// CHECK4-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16** null, i64 0, metadata [[META76:![0-9]+]]) +// CHECK4-NEXT: [[TMP19:%.*]] = call %struct.anon.16* @llvm.noalias.p0s_struct.anon.16s.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16* [[TMP8]], i8* [[TMP18]], %struct.anon.16** null, i64 0, metadata [[META76]]), !noalias !70 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !70 +// CHECK4-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: store %struct.anon.16* [[TMP19]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP20:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i32**, %struct.S**, %struct.S**)* +// CHECK4-NEXT: call void [[TMP23]](i8* [[TMP22]], i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR_I]], %struct.S** [[DOTLOCAL_PTR_ADDR1_I]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP24:%.*]] = load i32*, i32** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP25:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP26:%.*]] = load %struct.S*, %struct.S** [[DOTLOCAL_PTR_ADDR1_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP27:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4, !noalias !70 +// CHECK4-NEXT: switch i32 [[TMP28]], label [[DOTUNTIED_DONE__I:%.*]] [ // CHECK4-NEXT: i32 0, label [[DOTUNTIED_JMP__I:%.*]] // CHECK4-NEXT: i32 1, label [[DOTUNTIED_JMP_2_I:%.*]] // CHECK4-NEXT: i32 2, label [[DOTUNTIED_JMP_6_I:%.*]] @@ -4511,68 +4551,68 @@ // CHECK4-NEXT: i32 4, label [[DOTUNTIED_JMP_15_I:%.*]] // CHECK4-NEXT: ] // CHECK4: .untied.done..i: -// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK4-NEXT: store i32 1, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK4-NEXT: br label [[CLEANUP_I:%.*]] // CHECK4: .untied.jmp..i: -// CHECK4-NEXT: [[TMP21:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: store i32 1, i32* [[TMP21]], align 4 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP23:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP22]]) #[[ATTR4]] +// CHECK4-NEXT: [[TMP29:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: store i32 1, i32* [[TMP29]], align 4, !noalias !70 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP30:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP31:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM_I]], i8* [[TMP30]]) #[[ATTR4]], !noalias !70 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT:%.*]] // CHECK4: .untied.jmp.2.i: -// CHECK4-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S1_I]]) #[[ATTR4]] -// CHECK4-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S2_I]]) #[[ATTR4]] +// CHECK4-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S1_I]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S2_I]]) #[[ATTR4]], !noalias !70 // CHECK4-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S2_I]], i32 0, i32 0 -// CHECK4-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !112 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM3_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB23:[0-9]+]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP24:%.*]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3_I]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates.18*)* @.omp_task_entry..19 to i32 (i32, i8*)*)) #[[ATTR4]] -// CHECK4-NEXT: [[TMP25:%.*]] = bitcast i8* [[TMP24]] to %struct.kmp_task_t_with_privates.18* -// CHECK4-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18:%.*]], %struct.kmp_task_t_with_privates.18* [[TMP25]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP27:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP25]], i32 0, i32 2 -// CHECK4-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT__KMP_PRIVATES_T:%.*]], %struct..kmp_privates.t* [[TMP27]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP29:%.*]] = load i32, i32* [[TMP16]], align 128 -// CHECK4-NEXT: store i32 [[TMP29]], i32* [[TMP28]], align 128 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM4_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB23]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP30:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM4_I]], i8* [[TMP24]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP31:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: store i32 2, i32* [[TMP31]], align 4 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM5_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP32:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP33:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM5_I]], i8* [[TMP32]]) #[[ATTR4]] +// CHECK4-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !70 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM3_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB23:[0-9]+]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP32:%.*]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM3_I]], i32 1, i64 256, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates.18*)* @.omp_task_entry..19 to i32 (i32, i8*)*)) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP33:%.*]] = bitcast i8* [[TMP32]] to %struct.kmp_task_t_with_privates.18* +// CHECK4-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18:%.*]], %struct.kmp_task_t_with_privates.18* [[TMP33]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP35:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES_18]], %struct.kmp_task_t_with_privates.18* [[TMP33]], i32 0, i32 2 +// CHECK4-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT__KMP_PRIVATES_T:%.*]], %struct..kmp_privates.t* [[TMP35]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP37:%.*]] = load i32, i32* [[TMP24]], align 128, !noalias !70 +// CHECK4-NEXT: store i32 [[TMP37]], i32* [[TMP36]], align 128, !noalias !70 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM4_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB23]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP38:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM4_I]], i8* [[TMP32]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP39:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: store i32 2, i32* [[TMP39]], align 4, !noalias !70 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM5_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP40:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP41:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM5_I]], i8* [[TMP40]]) #[[ATTR4]], !noalias !70 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK4: .untied.jmp.6.i: -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM8_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP34:%.*]] = call i32 @__kmpc_omp_taskyield(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM8_I]], i32 0) #[[ATTR4]] -// CHECK4-NEXT: [[TMP35:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: store i32 3, i32* [[TMP35]], align 4 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM9_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP37:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM9_I]], i8* [[TMP36]]) #[[ATTR4]] +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM8_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP42:%.*]] = call i32 @__kmpc_omp_taskyield(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM8_I]], i32 0) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP43:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: store i32 3, i32* [[TMP43]], align 4, !noalias !70 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM9_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP44:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP45:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM9_I]], i8* [[TMP44]]) #[[ATTR4]], !noalias !70 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK4: .untied.jmp.10.i: -// CHECK4-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP38:%.*]] = bitcast %struct.S* [[S1_I]] to i8* -// CHECK4-NEXT: [[TMP39:%.*]] = bitcast %struct.S* [[REF_TMP_I]] to i8* -// CHECK4-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP38]], i8* align 4 [[TMP39]], i64 4, i1 false) #[[ATTR4]], !noalias !112 -// CHECK4-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]] +// CHECK4-NEXT: call void @_ZN1SC1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP46:%.*]] = bitcast %struct.S* [[S1_I]] to i8* +// CHECK4-NEXT: [[TMP47:%.*]] = bitcast %struct.S* [[REF_TMP_I]] to i8* +// CHECK4-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 [[TMP46]], i8* align 4 [[TMP47]], i64 4, i1 false) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[REF_TMP_I]]) #[[ATTR4]], !noalias !70 // CHECK4-NEXT: [[A12_I:%.*]] = getelementptr inbounds [[STRUCT_S]], %struct.S* [[S2_I]], i32 0, i32 0 -// CHECK4-NEXT: store i32 10, i32* [[A12_I]], align 4, !noalias !112 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM13_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP40:%.*]] = call i32 @__kmpc_omp_taskwait(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM13_I]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP41:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: store i32 4, i32* [[TMP41]], align 4 -// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM14_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]] -// CHECK4-NEXT: [[TMP42:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !112 -// CHECK4-NEXT: [[TMP43:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM14_I]], i8* [[TMP42]]) #[[ATTR4]] +// CHECK4-NEXT: store i32 10, i32* [[A12_I]], align 4, !noalias !70 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM13_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP48:%.*]] = call i32 @__kmpc_omp_taskwait(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM13_I]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP49:%.*]] = load i32*, i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: store i32 4, i32* [[TMP49]], align 4, !noalias !70 +// CHECK4-NEXT: [[OMP_GLOBAL_THREAD_NUM14_I:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB21]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: [[TMP50:%.*]] = load i8*, i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !70 +// CHECK4-NEXT: [[TMP51:%.*]] = call i32 @__kmpc_omp_task(%struct.ident_t* @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM14_I]], i8* [[TMP50]]) #[[ATTR4]], !noalias !70 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK4: .untied.jmp.15.i: -// CHECK4-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S2_I]]) #[[ATTR4]] -// CHECK4-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S1_I]]) #[[ATTR4]] -// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK4-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S2_I]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: call void @_ZN1SD1Ev(%struct.S* nonnull align 4 dereferenceable(4) [[S1_I]]) #[[ATTR4]], !noalias !70 +// CHECK4-NEXT: store i32 0, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK4-NEXT: br label [[CLEANUP_I]] // CHECK4: cleanup.i: -// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !112 +// CHECK4-NEXT: [[CLEANUP_DEST_I:%.*]] = load i32, i32* [[CLEANUP_DEST_SLOT_I]], align 4, !noalias !70 // CHECK4-NEXT: br label [[DOTOMP_OUTLINED__17_EXIT]] // CHECK4: .omp_outlined..17.exit: // CHECK4-NEXT: ret i32 0 @@ -4668,21 +4708,21 @@ // CHECK4-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK4-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.21* // CHECK4-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.22* [[TMP3]] to i8* -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META113:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META116:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META118:![0-9]+]]) -// CHECK4-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META120:![0-9]+]]) -// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !122 -// CHECK4-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !122 -// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !122 -// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !122 -// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !122 -// CHECK4-NEXT: store %struct.anon.21* [[TMP8]], %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !122 -// CHECK4-NEXT: [[TMP10:%.*]] = load %struct.anon.21*, %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !122 -// CHECK4-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_21:%.*]], %struct.anon.21* [[TMP10]], i32 0, i32 0 -// CHECK4-NEXT: [[TMP12:%.*]] = load %struct.S1*, %struct.S1** [[TMP11]], align 8 -// CHECK4-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP12]], i32 0, i32 0 -// CHECK4-NEXT: store i32 0, i32* [[A_I]], align 4 +// CHECK4-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META77:![0-9]+]]) +// CHECK4-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META77]]), !noalias !80 +// CHECK4-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.21s.i64(%struct.anon.21** null, i64 0, metadata [[META82:![0-9]+]]) +// CHECK4-NEXT: [[TMP13:%.*]] = call %struct.anon.21* @llvm.noalias.p0s_struct.anon.21s.p0i8.p0p0s_struct.anon.21s.i64(%struct.anon.21* [[TMP8]], i8* [[TMP12]], %struct.anon.21** null, i64 0, metadata [[META82]]), !noalias !80 +// CHECK4-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !80 +// CHECK4-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !80 +// CHECK4-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !80 +// CHECK4-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !80 +// CHECK4-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !80 +// CHECK4-NEXT: store %struct.anon.21* [[TMP13]], %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !80 +// CHECK4-NEXT: [[TMP14:%.*]] = load %struct.anon.21*, %struct.anon.21** [[__CONTEXT_ADDR_I]], align 8, !noalias !80 +// CHECK4-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_21:%.*]], %struct.anon.21* [[TMP14]], i32 0, i32 0 +// CHECK4-NEXT: [[TMP16:%.*]] = load %struct.S1*, %struct.S1** [[TMP15]], align 8, !noalias !80 +// CHECK4-NEXT: [[A_I:%.*]] = getelementptr inbounds [[STRUCT_S1:%.*]], %struct.S1* [[TMP16]], i32 0, i32 0 +// CHECK4-NEXT: store i32 0, i32* [[A_I]], align 4, !noalias !80 // CHECK4-NEXT: ret i32 0 // // Index: clang/test/OpenMP/task_firstprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/task_firstprivate_codegen.cpp +++ clang/test/OpenMP/task_firstprivate_codegen.cpp @@ -272,7 +272,8 @@ // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, // CHECK: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_DOUBLE_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**, [[S_DOUBLE_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.*]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**, [[S_DOUBLE_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -394,7 +395,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/task_if_codegen.cpp =================================================================== --- clang/test/OpenMP/task_if_codegen.cpp +++ clang/test/OpenMP/task_if_codegen.cpp @@ -134,18 +134,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: call void @_Z9gtid_testv() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META8:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META8]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: call void @_Z9gtid_testv() #[[ATTR3]], !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -238,18 +238,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: call void @_Z3fn7v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META11]]), !noalias !14 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META16]]), !noalias !14 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK1-NEXT: call void @_Z3fn7v() #[[ATTR3]], !noalias !14 // CHECK1-NEXT: ret i32 0 // // @@ -274,18 +274,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.2* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.3* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META32:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !34 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !34 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !34 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !34 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !34 -// CHECK1-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !34 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !34 -// CHECK1-NEXT: call void @_Z3fn8v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP12]], %struct.anon.2** null, i64 0, metadata [[META22]]), !noalias !20 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: store %struct.anon.2* [[TMP13]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK1-NEXT: call void @_Z3fn8v() #[[ATTR3]], !noalias !20 // CHECK1-NEXT: ret i32 0 // // @@ -310,18 +310,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.4* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.5* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META35:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META40:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META42:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !44 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !44 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !44 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !44 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !44 -// CHECK1-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 -// CHECK1-NEXT: call void @_Z3fn9v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META23]]), !noalias !26 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP12]], %struct.anon.4** null, i64 0, metadata [[META28]]), !noalias !26 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !26 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !26 +// CHECK1-NEXT: store %struct.anon.4* [[TMP13]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 +// CHECK1-NEXT: call void @_Z3fn9v() #[[ATTR3]], !noalias !26 // CHECK1-NEXT: ret i32 0 // // @@ -346,18 +346,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.6* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.7* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META45:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META52:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !54 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !54 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !54 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !54 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !54 -// CHECK1-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 -// CHECK1-NEXT: call void @_Z4fn10v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META29:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META29]]), !noalias !32 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META34:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP12]], %struct.anon.6** null, i64 0, metadata [[META34]]), !noalias !32 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: store %struct.anon.6* [[TMP13]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK1-NEXT: call void @_Z4fn10v() #[[ATTR3]], !noalias !32 // CHECK1-NEXT: ret i32 0 // // @@ -509,18 +509,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.8* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.9* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META55:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META62:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !64 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: store %struct.anon.8* [[TMP8]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK1-NEXT: call void @_Z3fn1v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META35:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META35]]), !noalias !38 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8** null, i64 0, metadata [[META40:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.8* @llvm.noalias.p0s_struct.anon.8s.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8* [[TMP8]], i8* [[TMP12]], %struct.anon.8** null, i64 0, metadata [[META40]]), !noalias !38 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !38 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !38 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !38 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !38 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !38 +// CHECK1-NEXT: store %struct.anon.8* [[TMP13]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !38 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !38 +// CHECK1-NEXT: call void @_Z3fn1v() #[[ATTR3]], !noalias !38 // CHECK1-NEXT: ret i32 0 // // @@ -545,18 +545,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.10* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.11* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META65:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META68:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META70:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META72:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !74 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !74 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !74 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !74 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !74 -// CHECK1-NEXT: store %struct.anon.10* [[TMP8]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !74 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !74 -// CHECK1-NEXT: call void @_Z3fn2v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META41:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META41]]), !noalias !44 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10** null, i64 0, metadata [[META46:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.10* @llvm.noalias.p0s_struct.anon.10s.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10* [[TMP8]], i8* [[TMP12]], %struct.anon.10** null, i64 0, metadata [[META46]]), !noalias !44 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !44 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !44 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !44 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !44 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !44 +// CHECK1-NEXT: store %struct.anon.10* [[TMP13]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 +// CHECK1-NEXT: call void @_Z3fn2v() #[[ATTR3]], !noalias !44 // CHECK1-NEXT: ret i32 0 // // @@ -581,18 +581,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.12* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.13* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META75:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META78:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META80:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META82:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !84 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !84 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !84 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !84 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !84 -// CHECK1-NEXT: store %struct.anon.12* [[TMP8]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !84 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !84 -// CHECK1-NEXT: call void @_Z3fn3v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META47:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META47]]), !noalias !50 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12** null, i64 0, metadata [[META52:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.12* @llvm.noalias.p0s_struct.anon.12s.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12* [[TMP8]], i8* [[TMP12]], %struct.anon.12** null, i64 0, metadata [[META52]]), !noalias !50 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !50 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !50 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !50 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !50 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !50 +// CHECK1-NEXT: store %struct.anon.12* [[TMP13]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !50 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !50 +// CHECK1-NEXT: call void @_Z3fn3v() #[[ATTR3]], !noalias !50 // CHECK1-NEXT: ret i32 0 // // @@ -617,18 +617,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.14* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.15* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META85:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META88:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META90:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META92:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !94 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !94 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !94 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !94 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !94 -// CHECK1-NEXT: store %struct.anon.14* [[TMP8]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !94 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !94 -// CHECK1-NEXT: call void @_Z3fn4v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META53:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META53]]), !noalias !56 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14** null, i64 0, metadata [[META58:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.14* @llvm.noalias.p0s_struct.anon.14s.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14* [[TMP8]], i8* [[TMP12]], %struct.anon.14** null, i64 0, metadata [[META58]]), !noalias !56 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !56 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !56 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !56 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !56 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !56 +// CHECK1-NEXT: store %struct.anon.14* [[TMP13]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !56 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !56 +// CHECK1-NEXT: call void @_Z3fn4v() #[[ATTR3]], !noalias !56 // CHECK1-NEXT: ret i32 0 // // @@ -653,18 +653,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.16* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.17* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META95:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META98:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META100:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META102:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !104 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !104 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !104 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !104 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !104 -// CHECK1-NEXT: store %struct.anon.16* [[TMP8]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !104 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !104 -// CHECK1-NEXT: call void @_Z3fn5v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META59:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META59]]), !noalias !62 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16** null, i64 0, metadata [[META64:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.16* @llvm.noalias.p0s_struct.anon.16s.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16* [[TMP8]], i8* [[TMP12]], %struct.anon.16** null, i64 0, metadata [[META64]]), !noalias !62 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 +// CHECK1-NEXT: store %struct.anon.16* [[TMP13]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 +// CHECK1-NEXT: call void @_Z3fn5v() #[[ATTR3]], !noalias !62 // CHECK1-NEXT: ret i32 0 // // @@ -689,18 +689,18 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.18* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.19* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META105:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META108:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META110:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META112:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !114 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !114 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !114 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !114 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !114 -// CHECK1-NEXT: store %struct.anon.18* [[TMP8]], %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !114 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.18*, %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !114 -// CHECK1-NEXT: call void @_Z3fn6v() #[[ATTR3]] +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META65:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META65]]), !noalias !68 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.18s.i64(%struct.anon.18** null, i64 0, metadata [[META70:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.18* @llvm.noalias.p0s_struct.anon.18s.p0i8.p0p0s_struct.anon.18s.i64(%struct.anon.18* [[TMP8]], i8* [[TMP12]], %struct.anon.18** null, i64 0, metadata [[META70]]), !noalias !68 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !68 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !68 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !68 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !68 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !68 +// CHECK1-NEXT: store %struct.anon.18* [[TMP13]], %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !68 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.18*, %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !68 +// CHECK1-NEXT: call void @_Z3fn6v() #[[ATTR3]], !noalias !68 // CHECK1-NEXT: ret i32 0 // // @@ -751,18 +751,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: call void @_Z9gtid_testv() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META8:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META8]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: call void @_Z9gtid_testv() #[[ATTR3]], !noalias !6 // CHECK2-NEXT: ret i32 0 // // @@ -855,18 +855,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: call void @_Z3fn7v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META11]]), !noalias !14 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META16]]), !noalias !14 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK2-NEXT: call void @_Z3fn7v() #[[ATTR3]], !noalias !14 // CHECK2-NEXT: ret i32 0 // // @@ -891,18 +891,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.2* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.3* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META32:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !34 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !34 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !34 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !34 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !34 -// CHECK2-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !34 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !34 -// CHECK2-NEXT: call void @_Z3fn8v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP12]], %struct.anon.2** null, i64 0, metadata [[META22]]), !noalias !20 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: store %struct.anon.2* [[TMP13]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK2-NEXT: call void @_Z3fn8v() #[[ATTR3]], !noalias !20 // CHECK2-NEXT: ret i32 0 // // @@ -927,18 +927,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.4* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.5* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META35:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META40:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META42:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !44 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !44 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !44 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !44 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !44 -// CHECK2-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 -// CHECK2-NEXT: call void @_Z3fn9v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META23]]), !noalias !26 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP12]], %struct.anon.4** null, i64 0, metadata [[META28]]), !noalias !26 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !26 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !26 +// CHECK2-NEXT: store %struct.anon.4* [[TMP13]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 +// CHECK2-NEXT: call void @_Z3fn9v() #[[ATTR3]], !noalias !26 // CHECK2-NEXT: ret i32 0 // // @@ -963,18 +963,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.6* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.7* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META45:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META52:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !54 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !54 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !54 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !54 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !54 -// CHECK2-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 -// CHECK2-NEXT: call void @_Z4fn10v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META29:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META29]]), !noalias !32 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META34:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP12]], %struct.anon.6** null, i64 0, metadata [[META34]]), !noalias !32 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: store %struct.anon.6* [[TMP13]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK2-NEXT: call void @_Z4fn10v() #[[ATTR3]], !noalias !32 // CHECK2-NEXT: ret i32 0 // // @@ -1126,18 +1126,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.8* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.9* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META55:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META62:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !64 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: store %struct.anon.8* [[TMP8]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK2-NEXT: call void @_Z3fn1v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META35:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META35]]), !noalias !38 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8** null, i64 0, metadata [[META40:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.8* @llvm.noalias.p0s_struct.anon.8s.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8* [[TMP8]], i8* [[TMP12]], %struct.anon.8** null, i64 0, metadata [[META40]]), !noalias !38 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !38 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !38 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !38 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !38 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !38 +// CHECK2-NEXT: store %struct.anon.8* [[TMP13]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !38 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !38 +// CHECK2-NEXT: call void @_Z3fn1v() #[[ATTR3]], !noalias !38 // CHECK2-NEXT: ret i32 0 // // @@ -1162,18 +1162,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.10* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.11* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META65:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META68:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META70:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META72:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !74 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !74 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !74 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !74 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !74 -// CHECK2-NEXT: store %struct.anon.10* [[TMP8]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !74 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !74 -// CHECK2-NEXT: call void @_Z3fn2v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META41:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META41]]), !noalias !44 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10** null, i64 0, metadata [[META46:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.10* @llvm.noalias.p0s_struct.anon.10s.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10* [[TMP8]], i8* [[TMP12]], %struct.anon.10** null, i64 0, metadata [[META46]]), !noalias !44 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !44 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !44 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !44 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !44 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !44 +// CHECK2-NEXT: store %struct.anon.10* [[TMP13]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 +// CHECK2-NEXT: call void @_Z3fn2v() #[[ATTR3]], !noalias !44 // CHECK2-NEXT: ret i32 0 // // @@ -1198,18 +1198,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.12* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.13* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META75:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META78:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META80:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META82:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !84 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !84 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !84 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !84 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !84 -// CHECK2-NEXT: store %struct.anon.12* [[TMP8]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !84 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !84 -// CHECK2-NEXT: call void @_Z3fn3v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META47:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META47]]), !noalias !50 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12** null, i64 0, metadata [[META52:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.12* @llvm.noalias.p0s_struct.anon.12s.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12* [[TMP8]], i8* [[TMP12]], %struct.anon.12** null, i64 0, metadata [[META52]]), !noalias !50 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !50 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !50 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !50 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !50 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !50 +// CHECK2-NEXT: store %struct.anon.12* [[TMP13]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !50 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !50 +// CHECK2-NEXT: call void @_Z3fn3v() #[[ATTR3]], !noalias !50 // CHECK2-NEXT: ret i32 0 // // @@ -1234,18 +1234,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.14* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.15* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META85:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META88:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META90:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META92:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !94 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !94 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !94 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !94 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !94 -// CHECK2-NEXT: store %struct.anon.14* [[TMP8]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !94 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !94 -// CHECK2-NEXT: call void @_Z3fn4v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META53:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META53]]), !noalias !56 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14** null, i64 0, metadata [[META58:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.14* @llvm.noalias.p0s_struct.anon.14s.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14* [[TMP8]], i8* [[TMP12]], %struct.anon.14** null, i64 0, metadata [[META58]]), !noalias !56 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !56 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !56 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !56 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !56 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !56 +// CHECK2-NEXT: store %struct.anon.14* [[TMP13]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !56 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !56 +// CHECK2-NEXT: call void @_Z3fn4v() #[[ATTR3]], !noalias !56 // CHECK2-NEXT: ret i32 0 // // @@ -1270,18 +1270,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.16* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.17* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META95:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META98:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META100:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META102:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !104 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !104 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !104 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !104 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !104 -// CHECK2-NEXT: store %struct.anon.16* [[TMP8]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !104 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !104 -// CHECK2-NEXT: call void @_Z3fn5v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META59:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META59]]), !noalias !62 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16** null, i64 0, metadata [[META64:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.16* @llvm.noalias.p0s_struct.anon.16s.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16* [[TMP8]], i8* [[TMP12]], %struct.anon.16** null, i64 0, metadata [[META64]]), !noalias !62 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 +// CHECK2-NEXT: store %struct.anon.16* [[TMP13]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 +// CHECK2-NEXT: call void @_Z3fn5v() #[[ATTR3]], !noalias !62 // CHECK2-NEXT: ret i32 0 // // @@ -1306,18 +1306,18 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.18* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.19* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META105:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META108:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META110:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META112:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !114 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !114 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !114 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !114 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !114 -// CHECK2-NEXT: store %struct.anon.18* [[TMP8]], %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !114 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.18*, %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !114 -// CHECK2-NEXT: call void @_Z3fn6v() #[[ATTR3]] +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META65:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META65]]), !noalias !68 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.18s.i64(%struct.anon.18** null, i64 0, metadata [[META70:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.18* @llvm.noalias.p0s_struct.anon.18s.p0i8.p0p0s_struct.anon.18s.i64(%struct.anon.18* [[TMP8]], i8* [[TMP12]], %struct.anon.18** null, i64 0, metadata [[META70]]), !noalias !68 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !68 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !68 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !68 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !68 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !68 +// CHECK2-NEXT: store %struct.anon.18* [[TMP13]], %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !68 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.18*, %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !68 +// CHECK2-NEXT: call void @_Z3fn6v() #[[ATTR3]], !noalias !68 // CHECK2-NEXT: ret i32 0 // // @@ -1368,18 +1368,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK5-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK5-NEXT: call void @_Z9gtid_testv() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META8:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META8]]), !noalias !6 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK5-NEXT: call void @_Z9gtid_testv() #[[ATTR3]], !noalias !6 // CHECK5-NEXT: ret i32 0 // // @@ -1472,18 +1472,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK5-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK5-NEXT: call void @_Z3fn7v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META11]]), !noalias !14 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META16]]), !noalias !14 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 +// CHECK5-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK5-NEXT: call void @_Z3fn7v() #[[ATTR3]], !noalias !14 // CHECK5-NEXT: ret i32 0 // // @@ -1508,18 +1508,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.2* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.3* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META32:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !34 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !34 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !34 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !34 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !34 -// CHECK5-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !34 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !34 -// CHECK5-NEXT: call void @_Z3fn8v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP12]], %struct.anon.2** null, i64 0, metadata [[META22]]), !noalias !20 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: store %struct.anon.2* [[TMP13]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK5-NEXT: call void @_Z3fn8v() #[[ATTR3]], !noalias !20 // CHECK5-NEXT: ret i32 0 // // @@ -1544,18 +1544,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.4* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.5* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META35:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META40:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META42:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !44 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !44 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !44 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !44 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !44 -// CHECK5-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 -// CHECK5-NEXT: call void @_Z3fn9v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META23]]), !noalias !26 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP12]], %struct.anon.4** null, i64 0, metadata [[META28]]), !noalias !26 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !26 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !26 +// CHECK5-NEXT: store %struct.anon.4* [[TMP13]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 +// CHECK5-NEXT: call void @_Z3fn9v() #[[ATTR3]], !noalias !26 // CHECK5-NEXT: ret i32 0 // // @@ -1580,18 +1580,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.6* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.7* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META45:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META52:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !54 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !54 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !54 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !54 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !54 -// CHECK5-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 -// CHECK5-NEXT: call void @_Z4fn10v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META29:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META29]]), !noalias !32 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META34:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP12]], %struct.anon.6** null, i64 0, metadata [[META34]]), !noalias !32 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 +// CHECK5-NEXT: store %struct.anon.6* [[TMP13]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK5-NEXT: call void @_Z4fn10v() #[[ATTR3]], !noalias !32 // CHECK5-NEXT: ret i32 0 // // @@ -1743,18 +1743,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.8* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.9* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META55:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META62:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !64 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !64 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !64 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !64 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !64 -// CHECK5-NEXT: store %struct.anon.8* [[TMP8]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK5-NEXT: call void @_Z3fn1v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META35:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META35]]), !noalias !38 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8** null, i64 0, metadata [[META40:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.8* @llvm.noalias.p0s_struct.anon.8s.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8* [[TMP8]], i8* [[TMP12]], %struct.anon.8** null, i64 0, metadata [[META40]]), !noalias !38 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !38 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !38 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !38 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !38 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !38 +// CHECK5-NEXT: store %struct.anon.8* [[TMP13]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !38 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !38 +// CHECK5-NEXT: call void @_Z3fn1v() #[[ATTR3]], !noalias !38 // CHECK5-NEXT: ret i32 0 // // @@ -1779,18 +1779,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.10* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.11* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META65:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META68:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META70:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META72:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !74 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !74 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !74 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !74 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !74 -// CHECK5-NEXT: store %struct.anon.10* [[TMP8]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !74 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !74 -// CHECK5-NEXT: call void @_Z3fn2v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META41:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META41]]), !noalias !44 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10** null, i64 0, metadata [[META46:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.10* @llvm.noalias.p0s_struct.anon.10s.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10* [[TMP8]], i8* [[TMP12]], %struct.anon.10** null, i64 0, metadata [[META46]]), !noalias !44 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !44 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !44 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !44 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !44 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !44 +// CHECK5-NEXT: store %struct.anon.10* [[TMP13]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 +// CHECK5-NEXT: call void @_Z3fn2v() #[[ATTR3]], !noalias !44 // CHECK5-NEXT: ret i32 0 // // @@ -1815,18 +1815,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.12* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.13* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META75:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META78:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META80:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META82:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !84 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !84 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !84 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !84 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !84 -// CHECK5-NEXT: store %struct.anon.12* [[TMP8]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !84 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !84 -// CHECK5-NEXT: call void @_Z3fn3v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META47:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META47]]), !noalias !50 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12** null, i64 0, metadata [[META52:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.12* @llvm.noalias.p0s_struct.anon.12s.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12* [[TMP8]], i8* [[TMP12]], %struct.anon.12** null, i64 0, metadata [[META52]]), !noalias !50 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !50 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !50 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !50 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !50 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !50 +// CHECK5-NEXT: store %struct.anon.12* [[TMP13]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !50 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !50 +// CHECK5-NEXT: call void @_Z3fn3v() #[[ATTR3]], !noalias !50 // CHECK5-NEXT: ret i32 0 // // @@ -1851,18 +1851,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.14* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.15* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META85:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META88:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META90:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META92:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !94 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !94 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !94 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !94 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !94 -// CHECK5-NEXT: store %struct.anon.14* [[TMP8]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !94 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !94 -// CHECK5-NEXT: call void @_Z3fn4v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META53:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META53]]), !noalias !56 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14** null, i64 0, metadata [[META58:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.14* @llvm.noalias.p0s_struct.anon.14s.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14* [[TMP8]], i8* [[TMP12]], %struct.anon.14** null, i64 0, metadata [[META58]]), !noalias !56 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !56 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !56 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !56 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !56 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !56 +// CHECK5-NEXT: store %struct.anon.14* [[TMP13]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !56 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !56 +// CHECK5-NEXT: call void @_Z3fn4v() #[[ATTR3]], !noalias !56 // CHECK5-NEXT: ret i32 0 // // @@ -1887,18 +1887,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.16* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.17* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META95:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META98:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META100:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META102:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !104 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !104 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !104 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !104 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !104 -// CHECK5-NEXT: store %struct.anon.16* [[TMP8]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !104 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !104 -// CHECK5-NEXT: call void @_Z3fn5v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META59:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META59]]), !noalias !62 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16** null, i64 0, metadata [[META64:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.16* @llvm.noalias.p0s_struct.anon.16s.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16* [[TMP8]], i8* [[TMP12]], %struct.anon.16** null, i64 0, metadata [[META64]]), !noalias !62 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 +// CHECK5-NEXT: store %struct.anon.16* [[TMP13]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 +// CHECK5-NEXT: call void @_Z3fn5v() #[[ATTR3]], !noalias !62 // CHECK5-NEXT: ret i32 0 // // @@ -1923,18 +1923,18 @@ // CHECK5-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK5-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.18* // CHECK5-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.19* [[TMP3]] to i8* -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META105:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META108:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META110:![0-9]+]]) -// CHECK5-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META112:![0-9]+]]) -// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !114 -// CHECK5-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !114 -// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !114 -// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !114 -// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !114 -// CHECK5-NEXT: store %struct.anon.18* [[TMP8]], %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !114 -// CHECK5-NEXT: [[TMP10:%.*]] = load %struct.anon.18*, %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !114 -// CHECK5-NEXT: call void @_Z3fn6v() #[[ATTR3]] +// CHECK5-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META65:![0-9]+]]) +// CHECK5-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META65]]), !noalias !68 +// CHECK5-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.18s.i64(%struct.anon.18** null, i64 0, metadata [[META70:![0-9]+]]) +// CHECK5-NEXT: [[TMP13:%.*]] = call %struct.anon.18* @llvm.noalias.p0s_struct.anon.18s.p0i8.p0p0s_struct.anon.18s.i64(%struct.anon.18* [[TMP8]], i8* [[TMP12]], %struct.anon.18** null, i64 0, metadata [[META70]]), !noalias !68 +// CHECK5-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !68 +// CHECK5-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !68 +// CHECK5-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !68 +// CHECK5-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !68 +// CHECK5-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !68 +// CHECK5-NEXT: store %struct.anon.18* [[TMP13]], %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !68 +// CHECK5-NEXT: [[TMP14:%.*]] = load %struct.anon.18*, %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !68 +// CHECK5-NEXT: call void @_Z3fn6v() #[[ATTR3]], !noalias !68 // CHECK5-NEXT: ret i32 0 // // @@ -1985,18 +1985,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK6-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK6-NEXT: call void @_Z9gtid_testv() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META8:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP12]], %struct.anon** null, i64 0, metadata [[META8]]), !noalias !6 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: store %struct.anon* [[TMP13]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK6-NEXT: call void @_Z9gtid_testv() #[[ATTR3]], !noalias !6 // CHECK6-NEXT: ret i32 0 // // @@ -2089,18 +2089,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.0* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.1* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK6-NEXT: store %struct.anon.0* [[TMP8]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK6-NEXT: call void @_Z3fn7v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META11]]), !noalias !14 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0** null, i64 0, metadata [[META16:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.0* @llvm.noalias.p0s_struct.anon.0s.p0i8.p0p0s_struct.anon.0s.i64(%struct.anon.0* [[TMP8]], i8* [[TMP12]], %struct.anon.0** null, i64 0, metadata [[META16]]), !noalias !14 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 +// CHECK6-NEXT: store %struct.anon.0* [[TMP13]], %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.0*, %struct.anon.0** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 +// CHECK6-NEXT: call void @_Z3fn7v() #[[ATTR3]], !noalias !14 // CHECK6-NEXT: ret i32 0 // // @@ -2125,18 +2125,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.2* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.3* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META28:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META30:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META32:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !34 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !34 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !34 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !34 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !34 -// CHECK6-NEXT: store %struct.anon.2* [[TMP8]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !34 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !34 -// CHECK6-NEXT: call void @_Z3fn8v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META17:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META17]]), !noalias !20 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2** null, i64 0, metadata [[META22:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.2* @llvm.noalias.p0s_struct.anon.2s.p0i8.p0p0s_struct.anon.2s.i64(%struct.anon.2* [[TMP8]], i8* [[TMP12]], %struct.anon.2** null, i64 0, metadata [[META22]]), !noalias !20 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !20 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: store %struct.anon.2* [[TMP13]], %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.2*, %struct.anon.2** [[__CONTEXT_ADDR_I]], align 8, !noalias !20 +// CHECK6-NEXT: call void @_Z3fn8v() #[[ATTR3]], !noalias !20 // CHECK6-NEXT: ret i32 0 // // @@ -2161,18 +2161,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.4* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.5* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META35:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META38:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META40:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META42:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !44 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !44 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !44 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !44 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !44 -// CHECK6-NEXT: store %struct.anon.4* [[TMP8]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 -// CHECK6-NEXT: call void @_Z3fn9v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META23:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META23]]), !noalias !26 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4** null, i64 0, metadata [[META28:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.4* @llvm.noalias.p0s_struct.anon.4s.p0i8.p0p0s_struct.anon.4s.i64(%struct.anon.4* [[TMP8]], i8* [[TMP12]], %struct.anon.4** null, i64 0, metadata [[META28]]), !noalias !26 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !26 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !26 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !26 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !26 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !26 +// CHECK6-NEXT: store %struct.anon.4* [[TMP13]], %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.4*, %struct.anon.4** [[__CONTEXT_ADDR_I]], align 8, !noalias !26 +// CHECK6-NEXT: call void @_Z3fn9v() #[[ATTR3]], !noalias !26 // CHECK6-NEXT: ret i32 0 // // @@ -2197,18 +2197,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.6* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.7* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META45:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META48:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META50:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META52:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !54 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !54 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !54 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !54 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !54 -// CHECK6-NEXT: store %struct.anon.6* [[TMP8]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !54 -// CHECK6-NEXT: call void @_Z4fn10v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META29:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META29]]), !noalias !32 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6** null, i64 0, metadata [[META34:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.6* @llvm.noalias.p0s_struct.anon.6s.p0i8.p0p0s_struct.anon.6s.i64(%struct.anon.6* [[TMP8]], i8* [[TMP12]], %struct.anon.6** null, i64 0, metadata [[META34]]), !noalias !32 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !32 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !32 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !32 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !32 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !32 +// CHECK6-NEXT: store %struct.anon.6* [[TMP13]], %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.6*, %struct.anon.6** [[__CONTEXT_ADDR_I]], align 8, !noalias !32 +// CHECK6-NEXT: call void @_Z4fn10v() #[[ATTR3]], !noalias !32 // CHECK6-NEXT: ret i32 0 // // @@ -2360,18 +2360,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.8* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.9* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META55:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META58:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META60:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META62:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !64 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !64 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !64 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !64 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !64 -// CHECK6-NEXT: store %struct.anon.8* [[TMP8]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !64 -// CHECK6-NEXT: call void @_Z3fn1v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META35:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META35]]), !noalias !38 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8** null, i64 0, metadata [[META40:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.8* @llvm.noalias.p0s_struct.anon.8s.p0i8.p0p0s_struct.anon.8s.i64(%struct.anon.8* [[TMP8]], i8* [[TMP12]], %struct.anon.8** null, i64 0, metadata [[META40]]), !noalias !38 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !38 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !38 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !38 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !38 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !38 +// CHECK6-NEXT: store %struct.anon.8* [[TMP13]], %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !38 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.8*, %struct.anon.8** [[__CONTEXT_ADDR_I]], align 8, !noalias !38 +// CHECK6-NEXT: call void @_Z3fn1v() #[[ATTR3]], !noalias !38 // CHECK6-NEXT: ret i32 0 // // @@ -2396,18 +2396,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.10* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.11* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META65:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META68:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META70:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META72:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !74 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !74 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !74 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !74 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !74 -// CHECK6-NEXT: store %struct.anon.10* [[TMP8]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !74 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !74 -// CHECK6-NEXT: call void @_Z3fn2v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META41:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META41]]), !noalias !44 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10** null, i64 0, metadata [[META46:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.10* @llvm.noalias.p0s_struct.anon.10s.p0i8.p0p0s_struct.anon.10s.i64(%struct.anon.10* [[TMP8]], i8* [[TMP12]], %struct.anon.10** null, i64 0, metadata [[META46]]), !noalias !44 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !44 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !44 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !44 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !44 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !44 +// CHECK6-NEXT: store %struct.anon.10* [[TMP13]], %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.10*, %struct.anon.10** [[__CONTEXT_ADDR_I]], align 8, !noalias !44 +// CHECK6-NEXT: call void @_Z3fn2v() #[[ATTR3]], !noalias !44 // CHECK6-NEXT: ret i32 0 // // @@ -2432,18 +2432,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.12* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.13* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META75:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META78:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META80:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META82:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !84 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !84 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !84 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !84 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !84 -// CHECK6-NEXT: store %struct.anon.12* [[TMP8]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !84 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !84 -// CHECK6-NEXT: call void @_Z3fn3v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META47:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META47]]), !noalias !50 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12** null, i64 0, metadata [[META52:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.12* @llvm.noalias.p0s_struct.anon.12s.p0i8.p0p0s_struct.anon.12s.i64(%struct.anon.12* [[TMP8]], i8* [[TMP12]], %struct.anon.12** null, i64 0, metadata [[META52]]), !noalias !50 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !50 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !50 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !50 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !50 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !50 +// CHECK6-NEXT: store %struct.anon.12* [[TMP13]], %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !50 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.12*, %struct.anon.12** [[__CONTEXT_ADDR_I]], align 8, !noalias !50 +// CHECK6-NEXT: call void @_Z3fn3v() #[[ATTR3]], !noalias !50 // CHECK6-NEXT: ret i32 0 // // @@ -2468,18 +2468,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.14* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.15* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META85:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META88:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META90:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META92:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !94 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !94 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !94 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !94 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !94 -// CHECK6-NEXT: store %struct.anon.14* [[TMP8]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !94 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !94 -// CHECK6-NEXT: call void @_Z3fn4v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META53:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META53]]), !noalias !56 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14** null, i64 0, metadata [[META58:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.14* @llvm.noalias.p0s_struct.anon.14s.p0i8.p0p0s_struct.anon.14s.i64(%struct.anon.14* [[TMP8]], i8* [[TMP12]], %struct.anon.14** null, i64 0, metadata [[META58]]), !noalias !56 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !56 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !56 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !56 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !56 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !56 +// CHECK6-NEXT: store %struct.anon.14* [[TMP13]], %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !56 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.14*, %struct.anon.14** [[__CONTEXT_ADDR_I]], align 8, !noalias !56 +// CHECK6-NEXT: call void @_Z3fn4v() #[[ATTR3]], !noalias !56 // CHECK6-NEXT: ret i32 0 // // @@ -2504,18 +2504,18 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.16* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.17* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META95:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META98:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META100:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META102:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !104 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !104 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !104 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !104 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !104 -// CHECK6-NEXT: store %struct.anon.16* [[TMP8]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !104 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !104 -// CHECK6-NEXT: call void @_Z3fn5v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META59:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META59]]), !noalias !62 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16** null, i64 0, metadata [[META64:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.16* @llvm.noalias.p0s_struct.anon.16s.p0i8.p0p0s_struct.anon.16s.i64(%struct.anon.16* [[TMP8]], i8* [[TMP12]], %struct.anon.16** null, i64 0, metadata [[META64]]), !noalias !62 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !62 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !62 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !62 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !62 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !62 +// CHECK6-NEXT: store %struct.anon.16* [[TMP13]], %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.16*, %struct.anon.16** [[__CONTEXT_ADDR_I]], align 8, !noalias !62 +// CHECK6-NEXT: call void @_Z3fn5v() #[[ATTR3]], !noalias !62 // CHECK6-NEXT: ret i32 0 // // @@ -2540,17 +2540,17 @@ // CHECK6-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK6-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.18* // CHECK6-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.19* [[TMP3]] to i8* -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META105:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META108:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META110:![0-9]+]]) -// CHECK6-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META112:![0-9]+]]) -// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !114 -// CHECK6-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !114 -// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !114 -// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !114 -// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !114 -// CHECK6-NEXT: store %struct.anon.18* [[TMP8]], %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !114 -// CHECK6-NEXT: [[TMP10:%.*]] = load %struct.anon.18*, %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !114 -// CHECK6-NEXT: call void @_Z3fn6v() #[[ATTR3]] +// CHECK6-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META65:![0-9]+]]) +// CHECK6-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META65]]), !noalias !68 +// CHECK6-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.18s.i64(%struct.anon.18** null, i64 0, metadata [[META70:![0-9]+]]) +// CHECK6-NEXT: [[TMP13:%.*]] = call %struct.anon.18* @llvm.noalias.p0s_struct.anon.18s.p0i8.p0p0s_struct.anon.18s.i64(%struct.anon.18* [[TMP8]], i8* [[TMP12]], %struct.anon.18** null, i64 0, metadata [[META70]]), !noalias !68 +// CHECK6-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !68 +// CHECK6-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !68 +// CHECK6-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !68 +// CHECK6-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !68 +// CHECK6-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !68 +// CHECK6-NEXT: store %struct.anon.18* [[TMP13]], %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !68 +// CHECK6-NEXT: [[TMP14:%.*]] = load %struct.anon.18*, %struct.anon.18** [[__CONTEXT_ADDR_I]], align 8, !noalias !68 +// CHECK6-NEXT: call void @_Z3fn6v() #[[ATTR3]], !noalias !68 // CHECK6-NEXT: ret i32 0 // Index: clang/test/OpenMP/task_in_reduction_codegen.cpp =================================================================== --- clang/test/OpenMP/task_in_reduction_codegen.cpp +++ clang/test/OpenMP/task_in_reduction_codegen.cpp @@ -588,51 +588,55 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP14:%.*]] = load i64, i64* [[TMP13]], align 8 -// CHECK1-NEXT: [[TMP15:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP16:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = bitcast void (i8*, ...)* [[TMP15]] to void (i8*, i8***, i8***)* -// CHECK1-NEXT: call void [[TMP17]](i8* [[TMP16]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK1-NEXT: [[TMP18:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP21:%.*]] = load i32*, i32** [[TMP20]], align 8 -// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK1-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP24:%.*]] = bitcast i32* [[TMP21]] to i8* -// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP23]], i8* [[TMP22]], i8* [[TMP24]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP25]] to i32* -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP27:%.*]] = load i16*, i16** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = mul nuw i64 [[TMP14]], 2 -// CHECK1-NEXT: [[TMP29:%.*]] = udiv exact i64 [[TMP28]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP23]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK1-NEXT: [[TMP31:%.*]] = bitcast i8* [[TMP30]] to i64* -// CHECK1-NEXT: store i64 [[TMP29]], i64* [[TMP31]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP19]], align 8 -// CHECK1-NEXT: [[TMP33:%.*]] = bitcast i16* [[TMP27]] to i8* -// CHECK1-NEXT: [[TMP34:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP23]], i8* [[TMP32]], i8* [[TMP33]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP34]] to i16* -// CHECK1-NEXT: [[TMP35:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP35]] to i64 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP22:%.*]] = load i64, i64* [[TMP21]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i8***, i8***)* +// CHECK1-NEXT: call void [[TMP25]](i8* [[TMP24]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP26:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP30:%.*]] = load i8*, i8** [[TMP26]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP32:%.*]] = bitcast i32* [[TMP29]] to i8* +// CHECK1-NEXT: [[TMP33:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP31]], i8* [[TMP30]], i8* [[TMP32]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP33]] to i32* +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP35:%.*]] = load i16*, i16** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = mul nuw i64 [[TMP22]], 2 +// CHECK1-NEXT: [[TMP37:%.*]] = udiv exact i64 [[TMP36]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP38:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP31]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP39:%.*]] = bitcast i8* [[TMP38]] to i64* +// CHECK1-NEXT: store i64 [[TMP37]], i64* [[TMP39]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[TMP27]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP41:%.*]] = bitcast i16* [[TMP35]] to i8* +// CHECK1-NEXT: [[TMP42:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP31]], i8* [[TMP40]], i8* [[TMP41]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP42]] to i16* +// CHECK1-NEXT: [[TMP43:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP43]] to i64 // CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK1-NEXT: [[TMP36:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2 -// CHECK1-NEXT: [[CONV3_I:%.*]] = sext i16 [[TMP36]] to i32 -// CHECK1-NEXT: [[TMP37:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK1-NEXT: [[ADD_I:%.*]] = add nsw i32 [[TMP37]], [[CONV3_I]] -// CHECK1-NEXT: store i32 [[ADD_I]], i32* [[CONV_I]], align 4 +// CHECK1-NEXT: [[TMP44:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6 +// CHECK1-NEXT: [[CONV3_I:%.*]] = sext i16 [[TMP44]] to i32 +// CHECK1-NEXT: [[TMP45:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[ADD_I:%.*]] = add nsw i32 [[TMP45]], [[CONV3_I]] +// CHECK1-NEXT: store i32 [[ADD_I]], i32* [[CONV_I]], align 4, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -657,26 +661,26 @@ // CHECK1-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK1-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.1* // CHECK1-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.2* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: store %struct.anon.1* [[TMP8]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP10:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP10]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8 -// CHECK1-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK1-NEXT: [[TMP14:%.*]] = bitcast i32* [[TMP12]] to i8* -// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP13]], i8* null, i8* [[TMP14]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP15]] to i32* -// CHECK1-NEXT: [[TMP16:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK1-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP16]], 1 -// CHECK1-NEXT: store i32 [[INC_I]], i32* [[CONV_I]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK1-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call %struct.anon.1* @llvm.noalias.p0s_struct.anon.1s.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1* [[TMP8]], i8* [[TMP12]], %struct.anon.1** null, i64 0, metadata [[META20]]), !noalias !18 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK1-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: store %struct.anon.1* [[TMP13]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP14:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP14]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32*, i32** [[TMP15]], align 8, !noalias !18 +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK1-NEXT: [[TMP18:%.*]] = bitcast i32* [[TMP16]] to i8* +// CHECK1-NEXT: [[TMP19:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP17]], i8* null, i8* [[TMP18]]) #[[ATTR3]], !noalias !18 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP19]] to i32* +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !18 +// CHECK1-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK1-NEXT: store i32 [[INC_I]], i32* [[CONV_I]], align 4, !noalias !18 // CHECK1-NEXT: ret i32 0 // // @@ -1259,51 +1263,55 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP14:%.*]] = load i64, i64* [[TMP13]], align 8 -// CHECK2-NEXT: [[TMP15:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP16:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = bitcast void (i8*, ...)* [[TMP15]] to void (i8*, i8***, i8***)* -// CHECK2-NEXT: call void [[TMP17]](i8* [[TMP16]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK2-NEXT: [[TMP18:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP21:%.*]] = load i32*, i32** [[TMP20]], align 8 -// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[TMP18]], align 8 -// CHECK2-NEXT: [[TMP23:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP24:%.*]] = bitcast i32* [[TMP21]] to i8* -// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP23]], i8* [[TMP22]], i8* [[TMP24]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP25]] to i32* -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP27:%.*]] = load i16*, i16** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = mul nuw i64 [[TMP14]], 2 -// CHECK2-NEXT: [[TMP29:%.*]] = udiv exact i64 [[TMP28]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP23]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK2-NEXT: [[TMP31:%.*]] = bitcast i8* [[TMP30]] to i64* -// CHECK2-NEXT: store i64 [[TMP29]], i64* [[TMP31]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP19]], align 8 -// CHECK2-NEXT: [[TMP33:%.*]] = bitcast i16* [[TMP27]] to i8* -// CHECK2-NEXT: [[TMP34:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP23]], i8* [[TMP32]], i8* [[TMP33]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP34]] to i16* -// CHECK2-NEXT: [[TMP35:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP35]] to i64 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP22:%.*]] = load i64, i64* [[TMP21]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = bitcast void (i8*, ...)* [[TMP23]] to void (i8*, i8***, i8***)* +// CHECK2-NEXT: call void [[TMP25]](i8* [[TMP24]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP26:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP29:%.*]] = load i32*, i32** [[TMP28]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP30:%.*]] = load i8*, i8** [[TMP26]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP31:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP32:%.*]] = bitcast i32* [[TMP29]] to i8* +// CHECK2-NEXT: [[TMP33:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP31]], i8* [[TMP30]], i8* [[TMP32]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP33]] to i32* +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP35:%.*]] = load i16*, i16** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = mul nuw i64 [[TMP22]], 2 +// CHECK2-NEXT: [[TMP37:%.*]] = udiv exact i64 [[TMP36]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP38:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP31]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP39:%.*]] = bitcast i8* [[TMP38]] to i64* +// CHECK2-NEXT: store i64 [[TMP37]], i64* [[TMP39]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[TMP27]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP41:%.*]] = bitcast i16* [[TMP35]] to i8* +// CHECK2-NEXT: [[TMP42:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP31]], i8* [[TMP40]], i8* [[TMP41]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP42]] to i16* +// CHECK2-NEXT: [[TMP43:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP43]] to i64 // CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK2-NEXT: [[TMP36:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2 -// CHECK2-NEXT: [[CONV3_I:%.*]] = sext i16 [[TMP36]] to i32 -// CHECK2-NEXT: [[TMP37:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK2-NEXT: [[ADD_I:%.*]] = add nsw i32 [[TMP37]], [[CONV3_I]] -// CHECK2-NEXT: store i32 [[ADD_I]], i32* [[CONV_I]], align 4 +// CHECK2-NEXT: [[TMP44:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6 +// CHECK2-NEXT: [[CONV3_I:%.*]] = sext i16 [[TMP44]] to i32 +// CHECK2-NEXT: [[TMP45:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[ADD_I:%.*]] = add nsw i32 [[TMP45]], [[CONV3_I]] +// CHECK2-NEXT: store i32 [[ADD_I]], i32* [[CONV_I]], align 4, !noalias !6 // CHECK2-NEXT: ret i32 0 // // @@ -1328,26 +1336,26 @@ // CHECK2-NEXT: [[TMP7:%.*]] = load i8*, i8** [[TMP6]], align 8 // CHECK2-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %struct.anon.1* // CHECK2-NEXT: [[TMP9:%.*]] = bitcast %struct.kmp_task_t_with_privates.2* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META18:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META22:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: store %struct.anon.1* [[TMP8]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP10:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !24 -// CHECK2-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP10]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP12:%.*]] = load i32*, i32** [[TMP11]], align 8 -// CHECK2-NEXT: [[TMP13:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !24 -// CHECK2-NEXT: [[TMP14:%.*]] = bitcast i32* [[TMP12]] to i8* -// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP13]], i8* null, i8* [[TMP14]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP15]] to i32* -// CHECK2-NEXT: [[TMP16:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK2-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP16]], 1 -// CHECK2-NEXT: store i32 [[INC_I]], i32* [[CONV_I]], align 4 +// CHECK2-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +// CHECK2-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP10]], i32** null, i64 0, metadata [[META15]]), !noalias !18 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1** null, i64 0, metadata [[META20:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call %struct.anon.1* @llvm.noalias.p0s_struct.anon.1s.p0i8.p0p0s_struct.anon.1s.i64(%struct.anon.1* [[TMP8]], i8* [[TMP12]], %struct.anon.1** null, i64 0, metadata [[META20]]), !noalias !18 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK2-NEXT: store i32* [[TMP11]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store i8* null, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store void (i8*, ...)* null, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store i8* [[TMP9]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: store %struct.anon.1* [[TMP13]], %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP14:%.*]] = load %struct.anon.1*, %struct.anon.1** [[__CONTEXT_ADDR_I]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP15:%.*]] = getelementptr inbounds [[STRUCT_ANON_1:%.*]], %struct.anon.1* [[TMP14]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP16:%.*]] = load i32*, i32** [[TMP15]], align 8, !noalias !18 +// CHECK2-NEXT: [[TMP17:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !18 +// CHECK2-NEXT: [[TMP18:%.*]] = bitcast i32* [[TMP16]] to i8* +// CHECK2-NEXT: [[TMP19:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP17]], i8* null, i8* [[TMP18]]) #[[ATTR3]], !noalias !18 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP19]] to i32* +// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !18 +// CHECK2-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK2-NEXT: store i32 [[INC_I]], i32* [[CONV_I]], align 4, !noalias !18 // CHECK2-NEXT: ret i32 0 // // Index: clang/test/OpenMP/task_private_codegen.cpp =================================================================== --- clang/test/OpenMP/task_private_codegen.cpp +++ clang/test/OpenMP/task_private_codegen.cpp @@ -229,7 +229,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.*]] = call void (i8*, ...)* @llvm.noalias.p0{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) @@ -341,7 +342,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/taskloop_firstprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_firstprivate_codegen.cpp +++ clang/test/OpenMP/taskloop_firstprivate_codegen.cpp @@ -275,7 +275,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -426,7 +427,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/taskloop_in_reduction_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_in_reduction_codegen.cpp +++ clang/test/OpenMP/taskloop_in_reduction_codegen.cpp @@ -594,73 +594,78 @@ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, i8***, i8***)* -// CHECK1-NEXT: call void [[TMP27]](i8* [[TMP26]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP28]], align 8 -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP34:%.*]] = bitcast i32* [[TMP31]] to i8* -// CHECK1-NEXT: [[TMP35:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP32]], i8* [[TMP34]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP35]] to i32* -// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP37:%.*]] = load i16*, i16** [[TMP36]], align 8 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP24]], 2 -// CHECK1-NEXT: [[TMP39:%.*]] = udiv exact i64 [[TMP38]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP33]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK1-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to i64* -// CHECK1-NEXT: store i64 [[TMP39]], i64* [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP29]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = bitcast i16* [[TMP37]] to i8* -// CHECK1-NEXT: [[TMP44:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP42]], i8* [[TMP43]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP44]] to i16* -// CHECK1-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK1-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK1-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK1-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, i8***, i8***)* +// CHECK1-NEXT: call void [[TMP37]](i8* [[TMP36]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP38:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP44:%.*]] = bitcast i32* [[TMP41]] to i8* +// CHECK1-NEXT: [[TMP45:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP42]], i8* [[TMP44]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP45]] to i32* +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP47:%.*]] = load i16*, i16** [[TMP46]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = mul nuw i64 [[TMP34]], 2 +// CHECK1-NEXT: [[TMP49:%.*]] = udiv exact i64 [[TMP48]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP50:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP43]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = bitcast i8* [[TMP50]] to i64* +// CHECK1-NEXT: store i64 [[TMP49]], i64* [[TMP51]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP53:%.*]] = bitcast i16* [[TMP47]] to i8* +// CHECK1-NEXT: [[TMP54:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP52]], i8* [[TMP53]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP54]] to i16* +// CHECK1-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK1-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK1-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP47]] +// CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK1-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP57]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP49]] to i64 +// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP59]] to i64 // CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK1-NEXT: [[TMP50:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2 -// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP50]] to i32 -// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP51]], [[CONV5_I]] -// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4 -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP60:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6 +// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP60]] to i32 +// CHECK1-NEXT: [[TMP61:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP61]], [[CONV5_I]] +// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK1: .omp_outlined..9.exit: // CHECK1-NEXT: ret i32 0 @@ -1264,73 +1269,78 @@ // CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, i8***, i8***)* -// CHECK2-NEXT: call void [[TMP27]](i8* [[TMP26]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK2-NEXT: [[TMP28:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP28]], align 8 -// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP34:%.*]] = bitcast i32* [[TMP31]] to i8* -// CHECK2-NEXT: [[TMP35:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP32]], i8* [[TMP34]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP35]] to i32* -// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP37:%.*]] = load i16*, i16** [[TMP36]], align 8 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP24]], 2 -// CHECK2-NEXT: [[TMP39:%.*]] = udiv exact i64 [[TMP38]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP33]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK2-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to i64* -// CHECK2-NEXT: store i64 [[TMP39]], i64* [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP29]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = bitcast i16* [[TMP37]] to i8* -// CHECK2-NEXT: [[TMP44:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP42]], i8* [[TMP43]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP44]] to i16* -// CHECK2-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK2-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK2-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK2-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, i8***, i8***)* +// CHECK2-NEXT: call void [[TMP37]](i8* [[TMP36]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP38:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP44:%.*]] = bitcast i32* [[TMP41]] to i8* +// CHECK2-NEXT: [[TMP45:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP42]], i8* [[TMP44]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP45]] to i32* +// CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP47:%.*]] = load i16*, i16** [[TMP46]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = mul nuw i64 [[TMP34]], 2 +// CHECK2-NEXT: [[TMP49:%.*]] = udiv exact i64 [[TMP48]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP50:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP43]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = bitcast i8* [[TMP50]] to i64* +// CHECK2-NEXT: store i64 [[TMP49]], i64* [[TMP51]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP53:%.*]] = bitcast i16* [[TMP47]] to i8* +// CHECK2-NEXT: [[TMP54:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP52]], i8* [[TMP53]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP54]] to i16* +// CHECK2-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK2-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK2-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP47]] +// CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK2-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP57]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP49]] to i64 +// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP59]] to i64 // CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK2-NEXT: [[TMP50:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2 -// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP50]] to i32 -// CHECK2-NEXT: [[TMP51:%.*]] = load i32, i32* [[CONV_I]], align 4 -// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP51]], [[CONV5_I]] -// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4 -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP60:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6 +// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP60]] to i32 +// CHECK2-NEXT: [[TMP61:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP61]], [[CONV5_I]] +// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]] // CHECK2: .omp_outlined..9.exit: // CHECK2-NEXT: ret i32 0 Index: clang/test/OpenMP/taskloop_lastprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_lastprivate_codegen.cpp +++ clang/test/OpenMP/taskloop_lastprivate_codegen.cpp @@ -267,7 +267,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -436,7 +437,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/taskloop_private_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_private_codegen.cpp +++ clang/test/OpenMP/taskloop_private_codegen.cpp @@ -229,7 +229,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) @@ -358,7 +359,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp +++ clang/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp @@ -275,7 +275,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -426,7 +427,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp +++ clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp @@ -594,73 +594,78 @@ // CHECK1-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK1-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, i8***, i8***)* -// CHECK1-NEXT: call void [[TMP27]](i8* [[TMP26]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK1-NEXT: [[TMP28:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK1-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP28]], align 8 -// CHECK1-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK1-NEXT: [[TMP34:%.*]] = bitcast i32* [[TMP31]] to i8* -// CHECK1-NEXT: [[TMP35:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP32]], i8* [[TMP34]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP35]] to i32* -// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP37:%.*]] = load i16*, i16** [[TMP36]], align 8 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP24]], 2 -// CHECK1-NEXT: [[TMP39:%.*]] = udiv exact i64 [[TMP38]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP33]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK1-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to i64* -// CHECK1-NEXT: store i64 [[TMP39]], i64* [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP29]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = bitcast i16* [[TMP37]] to i8* -// CHECK1-NEXT: [[TMP44:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP42]], i8* [[TMP43]]) #[[ATTR3]] -// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP44]] to i16* -// CHECK1-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK1-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK1-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK1-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK1-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, i8***, i8***)* +// CHECK1-NEXT: call void [[TMP37]](i8* [[TMP36]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP38:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP44:%.*]] = bitcast i32* [[TMP41]] to i8* +// CHECK1-NEXT: [[TMP45:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP42]], i8* [[TMP44]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP45]] to i32* +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP47:%.*]] = load i16*, i16** [[TMP46]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = mul nuw i64 [[TMP34]], 2 +// CHECK1-NEXT: [[TMP49:%.*]] = udiv exact i64 [[TMP48]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP50:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP43]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = bitcast i8* [[TMP50]] to i64* +// CHECK1-NEXT: store i64 [[TMP49]], i64* [[TMP51]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP53:%.*]] = bitcast i16* [[TMP47]] to i8* +// CHECK1-NEXT: [[TMP54:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP52]], i8* [[TMP53]]) #[[ATTR3]], !noalias !6 +// CHECK1-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP54]] to i16* +// CHECK1-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK1-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK1: omp.inner.for.cond.i: -// CHECK1-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK1-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP47]] +// CHECK1-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK1-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP57]] // CHECK1-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK1: omp.inner.for.body.i: -// CHECK1-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[TMP49:%.*]] = load i32, i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP49]] to i64 +// CHECK1-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[TMP59:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP59]] to i64 // CHECK1-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK1-NEXT: [[TMP50:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !llvm.access.group !15 -// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP50]] to i32 -// CHECK1-NEXT: [[TMP51:%.*]] = load i32, i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP51]], [[CONV5_I]] -// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK1-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK1-NEXT: [[TMP60:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP60]] to i32 +// CHECK1-NEXT: [[TMP61:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP61]], [[CONV5_I]] +// CHECK1-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK1-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK1-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK1-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK1: .omp_outlined..9.exit: // CHECK1-NEXT: ret i32 0 @@ -1264,73 +1269,78 @@ // CHECK2-NEXT: [[TMP19:%.*]] = load i32, i32* [[TMP18]], align 8 // CHECK2-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T]], %struct.kmp_task_t* [[TMP4]], i32 0, i32 9 // CHECK2-NEXT: [[TMP21:%.*]] = load i8*, i8** [[TMP20]], align 8 -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META12:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: store i8* [[TMP21]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP22:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP22]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP24:%.*]] = load i64, i64* [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP26:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP27:%.*]] = bitcast void (i8*, ...)* [[TMP25]] to void (i8*, i8***, i8***)* -// CHECK2-NEXT: call void [[TMP27]](i8* [[TMP26]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]] -// CHECK2-NEXT: [[TMP28:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP29:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 0 -// CHECK2-NEXT: [[TMP31:%.*]] = load i32*, i32** [[TMP30]], align 8 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[TMP28]], align 8 -// CHECK2-NEXT: [[TMP33:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !14 -// CHECK2-NEXT: [[TMP34:%.*]] = bitcast i32* [[TMP31]] to i8* -// CHECK2-NEXT: [[TMP35:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP32]], i8* [[TMP34]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP35]] to i32* -// CHECK2-NEXT: [[TMP36:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP22]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP37:%.*]] = load i16*, i16** [[TMP36]], align 8 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP24]], 2 -// CHECK2-NEXT: [[TMP39:%.*]] = udiv exact i64 [[TMP38]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP33]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]] -// CHECK2-NEXT: [[TMP41:%.*]] = bitcast i8* [[TMP40]] to i64* -// CHECK2-NEXT: store i64 [[TMP39]], i64* [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP29]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = bitcast i16* [[TMP37]] to i8* -// CHECK2-NEXT: [[TMP44:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP33]], i8* [[TMP42]], i8* [[TMP43]]) #[[ATTR3]] -// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP44]] to i16* -// CHECK2-NEXT: [[TMP45:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !14 -// CHECK2-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP45]] to i32 -// CHECK2-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14 +// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP23:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP22]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP25:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP24]], i8** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP26:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP27:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP26]], void (i8*, ...)** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META13:![0-9]+]]) +// CHECK2-NEXT: [[TMP29:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP21]], i8* [[TMP28]], i8** null, i64 0, metadata [[META13]]), !noalias !6 +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META14:![0-9]+]]) +// CHECK2-NEXT: [[TMP31:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP30]], %struct.anon** null, i64 0, metadata [[META14]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP23]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP25]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP27]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP13]], i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP15]], i64* [[DOTUB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i64 [[TMP17]], i64* [[DOTST__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i32 [[TMP19]], i32* [[DOTLITER__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP29]], i8** [[DOTREDUCTIONS__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP31]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP32:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP32]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP34:%.*]] = load i64, i64* [[TMP33]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP35:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = bitcast void (i8*, ...)* [[TMP35]] to void (i8*, i8***, i8***)* +// CHECK2-NEXT: call void [[TMP37]](i8* [[TMP36]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP38:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR1_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 0 +// CHECK2-NEXT: [[TMP41:%.*]] = load i32*, i32** [[TMP40]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP42:%.*]] = load i8*, i8** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP43:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP44:%.*]] = bitcast i32* [[TMP41]] to i8* +// CHECK2-NEXT: [[TMP45:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP42]], i8* [[TMP44]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP45]] to i32* +// CHECK2-NEXT: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP32]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP47:%.*]] = load i16*, i16** [[TMP46]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = mul nuw i64 [[TMP34]], 2 +// CHECK2-NEXT: [[TMP49:%.*]] = udiv exact i64 [[TMP48]], ptrtoint (i16* getelementptr (i16, i16* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP50:%.*]] = call i8* @__kmpc_threadprivate_cached(%struct.ident_t* @[[GLOB1]], i32 [[TMP43]], i8* bitcast (i64* @{{reduction_size[.].+[.]}}) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = bitcast i8* [[TMP50]] to i64* +// CHECK2-NEXT: store i64 [[TMP49]], i64* [[TMP51]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = load i8*, i8** [[TMP39]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP53:%.*]] = bitcast i16* [[TMP47]] to i8* +// CHECK2-NEXT: [[TMP54:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP43]], i8* [[TMP52]], i8* [[TMP53]]) #[[ATTR3]], !noalias !6 +// CHECK2-NEXT: [[CONV2_I:%.*]] = bitcast i8* [[TMP54]] to i16* +// CHECK2-NEXT: [[TMP55:%.*]] = load i64, i64* [[DOTLB__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[CONV3_I:%.*]] = trunc i64 [[TMP55]] to i32 +// CHECK2-NEXT: store i32 [[CONV3_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I:%.*]] // CHECK2: omp.inner.for.cond.i: -// CHECK2-NEXT: [[TMP46:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP46]] to i64 -// CHECK2-NEXT: [[TMP47:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP47]] +// CHECK2-NEXT: [[TMP56:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[CONV4_I:%.*]] = sext i32 [[TMP56]] to i64 +// CHECK2-NEXT: [[TMP57:%.*]] = load i64, i64* [[DOTUB__ADDR_I]], align 8, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[CMP_I:%.*]] = icmp ule i64 [[CONV4_I]], [[TMP57]] // CHECK2-NEXT: br i1 [[CMP_I]], label [[OMP_INNER_FOR_BODY_I:%.*]], label [[DOTOMP_OUTLINED__9_EXIT:%.*]] // CHECK2: omp.inner.for.body.i: -// CHECK2-NEXT: [[TMP48:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: store i32 [[TMP48]], i32* [[I_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[TMP49:%.*]] = load i32, i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP49]] to i64 +// CHECK2-NEXT: [[TMP58:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: store i32 [[TMP58]], i32* [[I_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[TMP59:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[IDXPROM_I:%.*]] = sext i32 [[TMP59]] to i64 // CHECK2-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds i16, i16* [[CONV2_I]], i64 [[IDXPROM_I]] -// CHECK2-NEXT: [[TMP50:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !llvm.access.group !15 -// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP50]] to i32 -// CHECK2-NEXT: [[TMP51:%.*]] = load i32, i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP51]], [[CONV5_I]] -// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !llvm.access.group !15 -// CHECK2-NEXT: [[TMP52:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 -// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP52]], 1 -// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !14, !llvm.access.group !15 +// CHECK2-NEXT: [[TMP60:%.*]] = load i16, i16* [[ARRAYIDX_I]], align 2, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[CONV5_I:%.*]] = sext i16 [[TMP60]] to i32 +// CHECK2-NEXT: [[TMP61:%.*]] = load i32, i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[ADD6_I:%.*]] = add nsw i32 [[TMP61]], [[CONV5_I]] +// CHECK2-NEXT: store i32 [[ADD6_I]], i32* [[CONV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[TMP62:%.*]] = load i32, i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 +// CHECK2-NEXT: [[ADD7_I:%.*]] = add nsw i32 [[TMP62]], 1 +// CHECK2-NEXT: store i32 [[ADD7_I]], i32* [[DOTOMP_IV_I]], align 4, !noalias !6, !llvm.access.group !15 // CHECK2-NEXT: br label [[OMP_INNER_FOR_COND_I]], !llvm.loop [[LOOP16:![0-9]+]] // CHECK2: .omp_outlined..9.exit: // CHECK2-NEXT: ret i32 0 Index: clang/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp +++ clang/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp @@ -265,7 +265,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, @@ -434,7 +435,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/taskloop_simd_private_codegen.cpp =================================================================== --- clang/test/OpenMP/taskloop_simd_private_codegen.cpp +++ clang/test/OpenMP/taskloop_simd_private_codegen.cpp @@ -229,7 +229,8 @@ // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) @@ -358,7 +359,8 @@ // CHECK-DAG: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, // CHECK-DAG: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_INT_TY]]]*, // CHECK-DAG: [[PRIV_VAR_ADDR:%.+]] = alloca [[S_INT_TY]]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIVATES_MAP_FN_NOALIAS:%.+]] = call void (i8*, ...)* @llvm.noalias.p0f{{.*}}(void (i8*, ...)* bitcast (void ([[PRIVATES_TMAIN_TY]]*, i32**, [2 x i32]**, [2 x [[S_INT_TY]]]**, [[S_INT_TY]]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), +// CHECK: store void (i8*, ...)* [[PRIVATES_MAP_FN_NOALIAS]], void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* [[MAP_FN]] to void (i8*, // CHECK: call void [[FN]](i8* %{{.+}}, i32** [[PRIV_T_VAR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], [2 x [[S_INT_TY]]]** [[PRIV_S_ARR_ADDR]], [[S_INT_TY]]** [[PRIV_VAR_ADDR]]) Index: clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp =================================================================== --- clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp +++ clang/test/OpenMP/teams_distribute_parallel_for_reduction_task_codegen.cpp @@ -817,61 +817,65 @@ // CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK1-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK1-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK1-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK1-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK1-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK1-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK1-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK1-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK1-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK1-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK1-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK1-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK1-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK1-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK1-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK1-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK1-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK1-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK1-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK1-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK1-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK1-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK1-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK1-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK1-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK1-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK1-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK1-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK1-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK1-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK1-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK1-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK1-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK1-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK1-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK1-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK1-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK1-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK1-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK1-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK1-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK1-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK1-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK1-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK1-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK1-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK1-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK1-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK1-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK1-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK1-NEXT: ret i32 0 // // @@ -1754,61 +1758,65 @@ // CHECK2-NEXT: [[TMP9:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_T_WITH_PRIVATES]], %struct.kmp_task_t_with_privates* [[TMP3]], i32 0, i32 1 // CHECK2-NEXT: [[TMP10:%.*]] = bitcast %struct..kmp_privates.t* [[TMP9]] to i8* // CHECK2-NEXT: [[TMP11:%.*]] = bitcast %struct.kmp_task_t_with_privates* [[TMP3]] to i8* -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) -// CHECK2-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) -// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: store i32* [[TMP5]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP10]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: store %struct.anon* [[TMP8]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP12:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP13:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP14:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP15:%.*]] = bitcast void (i8*, ...)* [[TMP13]] to void (i8*, i8***)* -// CHECK2-NEXT: call void [[TMP15]](i8* [[TMP14]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP16:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !12 -// CHECK2-NEXT: [[TMP17:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP18:%.*]] = load i32*, i32** [[TMP17]], align 8 -// CHECK2-NEXT: [[TMP19:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP20:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !12 -// CHECK2-NEXT: [[TMP21:%.*]] = bitcast i32* [[TMP18]] to i8* -// CHECK2-NEXT: [[TMP22:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP19]], i8* [[TMP21]]) #[[ATTR5]] -// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP22]] to i32* -// CHECK2-NEXT: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[TMP23]], align 8 -// CHECK2-NEXT: [[TMP25:%.*]] = load i8*, i8** [[TMP24]], align 8 -// CHECK2-NEXT: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 1 -// CHECK2-NEXT: [[TMP27:%.*]] = load i32*, i32** [[TMP26]], align 8 -// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[TMP27]], align 4 -// CHECK2-NEXT: [[TMP29:%.*]] = sext i32 [[TMP28]] to i64 -// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP29]] -// CHECK2-NEXT: [[TMP30:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP31:%.*]] = load i8**, i8*** [[TMP30]], align 8 -// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP31]], i64 9 -// CHECK2-NEXT: [[TMP32:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8 -// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP32]], i64 [[LB_ADD_LEN_I]] -// CHECK2-NEXT: [[TMP33:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 -// CHECK2-NEXT: [[TMP34:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP35:%.*]] = sub i64 [[TMP33]], [[TMP34]] -// CHECK2-NEXT: [[TMP36:%.*]] = sdiv exact i64 [[TMP35]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP37:%.*]] = add nuw i64 [[TMP36]], 1 -// CHECK2-NEXT: [[TMP38:%.*]] = mul nuw i64 [[TMP37]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: store i64 [[TMP37]], i64* @{{reduction_size[.].+[.]}}, align 8 -// CHECK2-NEXT: [[TMP39:%.*]] = load i8*, i8** [[TMP16]], align 8 -// CHECK2-NEXT: [[TMP40:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP20]], i8* [[TMP39]], i8* [[TMP25]]) #[[ATTR5]] -// CHECK2-NEXT: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP12]], i32 0, i32 2 -// CHECK2-NEXT: [[TMP42:%.*]] = load i8**, i8*** [[TMP41]], align 8 -// CHECK2-NEXT: [[TMP43:%.*]] = load i8*, i8** [[TMP42]], align 8 -// CHECK2-NEXT: [[TMP44:%.*]] = ptrtoint i8* [[TMP43]] to i64 -// CHECK2-NEXT: [[TMP45:%.*]] = ptrtoint i8* [[TMP25]] to i64 -// CHECK2-NEXT: [[TMP46:%.*]] = sub i64 [[TMP44]], [[TMP45]] -// CHECK2-NEXT: [[TMP47:%.*]] = sdiv exact i64 [[TMP46]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) -// CHECK2-NEXT: [[TMP48:%.*]] = getelementptr i8, i8* [[TMP40]], i64 [[TMP47]] -// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !12 -// CHECK2-NEXT: store i8* [[TMP48]], i8** [[TMP4_I]], align 8, !noalias !12 +// CHECK2-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +// CHECK2-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[TMP5]], i8* [[TMP12]], i32** null, i64 0, metadata [[META3]]), !noalias !6 +// CHECK2-NEXT: [[TMP14:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META10:![0-9]+]]) +// CHECK2-NEXT: [[TMP15:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[TMP10]], i8* [[TMP14]], i8** null, i64 0, metadata [[META10]]), !noalias !6 +// CHECK2-NEXT: [[TMP16:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)** null, i64 0, metadata [[META11:![0-9]+]]) +// CHECK2-NEXT: [[TMP17:%.*]] = call void (i8*, ...)* @llvm.noalias.p0f_isVoidp0i8varargf.p0i8.p0p0f_isVoidp0i8varargf.i64(void (i8*, ...)* bitcast (void (%struct..kmp_privates.t*, i8***)* @.omp_task_privates_map. to void (i8*, ...)*), i8* [[TMP16]], void (i8*, ...)** null, i64 0, metadata [[META11]]), !noalias !6 +// CHECK2-NEXT: [[TMP18:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.anons.i64(%struct.anon** null, i64 0, metadata [[META12:![0-9]+]]) +// CHECK2-NEXT: [[TMP19:%.*]] = call %struct.anon* @llvm.noalias.p0s_struct.anons.p0i8.p0p0s_struct.anons.i64(%struct.anon* [[TMP8]], i8* [[TMP18]], %struct.anon** null, i64 0, metadata [[META12]]), !noalias !6 +// CHECK2-NEXT: store i32 [[TMP2]], i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: store i32* [[TMP13]], i32** [[DOTPART_ID__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP15]], i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store void (i8*, ...)* [[TMP17]], void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP11]], i8** [[DOTTASK_T__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: store %struct.anon* [[TMP19]], %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP20:%.*]] = load %struct.anon*, %struct.anon** [[__CONTEXT_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP21:%.*]] = load void (i8*, ...)*, void (i8*, ...)** [[DOTCOPY_FN__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP22:%.*]] = load i8*, i8** [[DOTPRIVATES__ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP23:%.*]] = bitcast void (i8*, ...)* [[TMP21]] to void (i8*, i8***)* +// CHECK2-NEXT: call void [[TMP23]](i8* [[TMP22]], i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP24:%.*]] = load i8**, i8*** [[DOTFIRSTPRIV_PTR_ADDR_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP26:%.*]] = load i32*, i32** [[TMP25]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP27:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP28:%.*]] = load i32, i32* [[DOTGLOBAL_TID__ADDR_I]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP29:%.*]] = bitcast i32* [[TMP26]] to i8* +// CHECK2-NEXT: [[TMP30:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP27]], i8* [[TMP29]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[CONV_I:%.*]] = bitcast i8* [[TMP30]] to i32* +// CHECK2-NEXT: [[TMP31:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP32:%.*]] = load i8**, i8*** [[TMP31]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP33:%.*]] = load i8*, i8** [[TMP32]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP34:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 1 +// CHECK2-NEXT: [[TMP35:%.*]] = load i32*, i32** [[TMP34]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP36:%.*]] = load i32, i32* [[TMP35]], align 4, !noalias !6 +// CHECK2-NEXT: [[TMP37:%.*]] = sext i32 [[TMP36]] to i64 +// CHECK2-NEXT: [[LB_ADD_LEN_I:%.*]] = add nsw i64 -1, [[TMP37]] +// CHECK2-NEXT: [[TMP38:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP39:%.*]] = load i8**, i8*** [[TMP38]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX2_I:%.*]] = getelementptr inbounds i8*, i8** [[TMP39]], i64 9 +// CHECK2-NEXT: [[TMP40:%.*]] = load i8*, i8** [[ARRAYIDX2_I]], align 8, !noalias !6 +// CHECK2-NEXT: [[ARRAYIDX3_I:%.*]] = getelementptr inbounds i8, i8* [[TMP40]], i64 [[LB_ADD_LEN_I]] +// CHECK2-NEXT: [[TMP41:%.*]] = ptrtoint i8* [[ARRAYIDX3_I]] to i64 +// CHECK2-NEXT: [[TMP42:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP43:%.*]] = sub i64 [[TMP41]], [[TMP42]] +// CHECK2-NEXT: [[TMP44:%.*]] = sdiv exact i64 [[TMP43]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP45:%.*]] = add nuw i64 [[TMP44]], 1 +// CHECK2-NEXT: [[TMP46:%.*]] = mul nuw i64 [[TMP45]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: store i64 [[TMP45]], i64* @{{reduction_size[.].+[.]}}, align 8, !noalias !6 +// CHECK2-NEXT: [[TMP47:%.*]] = load i8*, i8** [[TMP24]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP48:%.*]] = call i8* @__kmpc_task_reduction_get_th_data(i32 [[TMP28]], i8* [[TMP47]], i8* [[TMP33]]) #[[ATTR5]], !noalias !6 +// CHECK2-NEXT: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_ANON]], %struct.anon* [[TMP20]], i32 0, i32 2 +// CHECK2-NEXT: [[TMP50:%.*]] = load i8**, i8*** [[TMP49]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP51:%.*]] = load i8*, i8** [[TMP50]], align 8, !noalias !6 +// CHECK2-NEXT: [[TMP52:%.*]] = ptrtoint i8* [[TMP51]] to i64 +// CHECK2-NEXT: [[TMP53:%.*]] = ptrtoint i8* [[TMP33]] to i64 +// CHECK2-NEXT: [[TMP54:%.*]] = sub i64 [[TMP52]], [[TMP53]] +// CHECK2-NEXT: [[TMP55:%.*]] = sdiv exact i64 [[TMP54]], ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64) +// CHECK2-NEXT: [[TMP56:%.*]] = getelementptr i8, i8* [[TMP48]], i64 [[TMP55]] +// CHECK2-NEXT: store i8** [[TMP4_I]], i8*** [[TMP_I]], align 8, !noalias !6 +// CHECK2-NEXT: store i8* [[TMP56]], i8** [[TMP4_I]], align 8, !noalias !6 // CHECK2-NEXT: ret i32 0 // // Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -6041,6 +6041,8 @@ 4 byte gap between the two fields. This gap represents padding which does not carry useful data and need not be preserved. +.. _noalias_and_aliasscope: + '``noalias``' and '``alias.scope``' Metadata ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9791,8 +9793,8 @@ :: - = load [volatile] , * [, align ][, !nontemporal !][, !invariant.load !][, !invariant.group !][, !nonnull !][, !dereferenceable !][, !dereferenceable_or_null !][, !align !][, !noundef !] - = load atomic [volatile] , * [syncscope("")] , align [, !invariant.group !] + = load [volatile] , * [, ptr_provenance * ][,align ][, !nontemporal !][, !invariant.load !][, !invariant.group !][, !nonnull !][, !dereferenceable !][, !dereferenceable_or_null !][, !align !][, !noundef !] + = load atomic [volatile] , * [, ptr_provenance * ] [syncscope("")] , align [, !invariant.group !] ! = !{ i32 1 } ! = !{} ! = !{ i64 } @@ -9824,6 +9826,13 @@ alignment is not set to a value which is at least the size in bytes of the pointee. ``!nontemporal`` does not have any defined semantics for atomic loads. +The optional ``ptr_provenance`` argument specifies the noalias chain of the +pointer operand. It has the same type as the pointer operand. Together with the +``!noalias`` metadata on the instruction, and the ``llvm.provenance.noalias``, +``llvm.noalias.arg.guard`` intrinsics in the chain, this is used to deduce if +two load/store instructions may or may not alias. (See `Scoped NoAlias Related +Intrinsics`_) + The optional constant ``align`` argument specifies the alignment of the operation (that is, the alignment of the memory address). A value of 0 or an omitted ``align`` argument means that the operation has the ABI @@ -9926,8 +9935,8 @@ :: - store [volatile] , * [, align ][, !nontemporal !][, !invariant.group !] ; yields void - store atomic [volatile] , * [syncscope("")] , align [, !invariant.group !] ; yields void + store [volatile] , * [, ptr_provenance * ][, align ][, !nontemporal !][, !invariant.group !] ; yields void + store atomic [volatile] , * [, ptr_provenance * ] [syncscope("")] , align [, !invariant.group !] ; yields void ! = !{ i32 1 } ! = !{} @@ -9959,6 +9968,13 @@ the alignment is not set to a value which is at least the size in bytes of the pointee. ``!nontemporal`` does not have any defined semantics for atomic stores. +The optional ``ptr_provenance`` argument specifies the noalias chain of the +pointer operand. It has the same type as the pointer operand. Together with the +``!noalias`` metadata on the instruction, and the ``llvm.provenance.noalias``, +``llvm.noalias.arg.guard`` intrinsics in the chain, this is used to deduce if +two load/store instructions may or may not alias. (See `Scoped NoAlias Related +Intrinsics`_) + The optional constant ``align`` argument specifies the alignment of the operation (that is, the alignment of the memory address). A value of 0 or an omitted ``align`` argument means that the operation has the ABI @@ -22097,6 +22113,312 @@ by the verifier as they indicate a problem in either a transformation pass or the input. +Scoped NoAlias Related Intrinsics +--------------------------------- + +This set of intrinsics provide the basis for full C99 '``restrict``' support +(See: iso-C99-n1256, 6.7.3.1 'Formal definition of restrict'). + +In C99 restrict, accesses using a pointer based on a restrict pointer ``p`` +are assumed to not alias with other accesses that are not based on ``p``, as +long as both accesses are within the scope of the declaration of ``p``. + +The intrinsics work together with the '``!noalias``' +:ref:`metadata ` annotations on memory instructions and +the ``ptr_provenance`` of ``load`` and ``store`` instructions. + +The full set of intrinsics is: + +.. code-block:: llvm + + %p.decl = i8* @llvm.noalias.decl.XXX(i8** %p.alloc, i32 , metadata !p.scope) + %p.noalias = i8* @llvm.noalias.XXX(i8* %p, i8* %p.decl, i8** %p.addr, + i32 , metadata !p.scope) !noalias !VisibleScopes + %prov.p = i8* @llvm.provenance.noalias.XXX(i8* %prov.p, i8* %p.decl, + i8** p.addr, i8** %prov.p.addr, + i32 , metadata !p.scope) !noalias !VisibleScopes + %p.guard = i8* @llvm.noalias.arg.guard.XXX(i8* %p, i8* %prov.p) + %p.copy.guard = %struct.FOO* @llvm.noalias.copy.guard.XXX(%struct.FOO* %p.block, i8* %p.decl, + metadata !p.indices, metadata !p.scope) + + +A detailed description of these intrinsics and how the work is explained in +::doc::`Restrict and NoAlias Information in LLVM ` + +.. _int_noalias_decl: + +'``llvm.noalias.decl``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. The return type and argument types are encoded +in ``XXX``. + +:: + + declare i8* @llvm.noalias.decl.XXX(* %p.alloca, i32 , metadata !p.scope) + +Overview: +""""""""" + +``llvm.noalias.decl`` is inserted at the location of a restrict pointer +declaration. It makes it possible to identify that a restrict scope is only +valid inside the body of a loop. It also makes it possible to identify that a +certain ``alloca`` is associated to an object that contains one or more +restrict pointers. + +The handle it returns is always of type ``i8*`` and does +not really represent a value. It is merely used to track a dependency on the +declaration. + +Arguments: +"""""""""" + +The first argument ``%p.alloca`` points to the ``alloca`` that contains one +or more restrict pointers. It can also be ``null`` if the ``alloca`` has been +optimized away. + +The second argument ``p.objId`` is an integer representing an object id. + +The third argument ``!p.scope`` is metadata that is a list of ``noalias`` +metadata references. The format is identical to that required for ``noalias`` +metadata. This list must have exactly one element. + +Semantics: +"""""""""" + +The ``llvm.noalias.decl`` intrinsic is used to identify the exact location of +a *restrict pointer declaration*. When this is done inside the loop body, +care must be taken to duplicate and uniquify the scopes and intrinsics when +the loop is unrolled. Otherwise the restrict scope could spill across +iterations. + +It also associates specific restrict properties to an ``alloca`` and is used +to propagate those properties to ``llvm.noalias``, ``llvm.provenance.noalias`` and +``llvm.noalias.copy.guard`` intrinsics when inlining and optimizations make +the relationship between those intrinsics and the actual variable declaration +visible. + +A detailed description of these intrinsics and how the work is explained in +::doc::`Restrict and NoAlias Information in LLVM ` + +.. _int_noalias: + +'``llvm.noalias``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. The return type and argument types are encoded +in ``XXX``. + +:: + + declare * @llvm.noalias.XXX(* %p, i8* %p.decl, ** %p.addr, + i32 , metadata !p.scope) + +Overview: +""""""""" + +``llvm.noalias`` is inserted at the moment that restrict properties are +introduced. This is typically done after loading a restrict pointer from +memory. Its return value can be seen as *the pointer value with restrict +properties* + +Arguments: +"""""""""" + +The first argument ``%p`` is the pointer on which the aliasing assumption is +being placed. + +The second argument ``%p.decl`` refers to the ``llvm.noalias.decl`` that is +associated with the pointer declaration. + +The third argument ``%p.addr`` is the address in memory of this pointer. + +The fourth argument ``p.objId`` is an integer representing an object id. + +The fifth argument ``!p.scope`` is metadata that is a list of ``noalias`` +metadata references. The format is identical to that required for ``noalias`` +metadata. This list must have exactly one element. + +Semantics: +"""""""""" + +The ``llvm.noalias`` intrinsic adds alias assumptions to the pointer +computation path. It also blocks optimizations on this computation path. + +It will be transformed into a ``llvm.provenance.noalias`` intrinsic and moved onto +the ``ptr_provenance`` path, so that pointer optimizations can still be +done and the restrict information is not lost. + +A detailed description of these intrinsics and how the work is explained in +::doc::`Restrict and NoAlias Information in LLVM ` + +.. _int_provenance_noalias: + +'``llvm.provenance.noalias``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. The return type and argument types are encoded +in ``XXX``. + +:: + + declare * @llvm.provenance.noalias.XXX(* %p, i8* %p.decl, + ** %p.addr, ** %prov.p.addr, + i32 , metadata !p.scope) + +Overview: +""""""""" + +``llvm.provenance.noalias`` is inserted at the moment that restrict properties are +introduced on the ``ptr_provenance``. This is typically done when a +``llvm.noalias`` is converted into the ``llvm.provenance.noalias`` + +The value it returns (``%prov.p``) is representing the pointer ``%p`` on the +``ptr_provenance``. + +Arguments: +"""""""""" + +The first argument ``%p`` is the pointer (or its ``ptr_provenance``) on +which the aliasing assumption is being placed. + +The second argument ``%p.decl`` refers to the ``llvm.noalias.decl`` that is +associated with the pointer declaration. + +The third argument ``%p.addr`` is the address in memory of this pointer. + +The fourth argument ``%prov.p.addr`` represents ``%p.addr`` on the +``ptr_provenance``. + +The fifth argument ``p.objId`` is an integer representing an object id. + +The sixth argument ``!p.scope`` is metadata that is a list of ``noalias`` +metadata references. The format is identical to that required for ``noalias`` +metadata. This list must have exactly one element. + + +Semantics: +"""""""""" + +The ``llvm.provenance.noalias`` intrinsic adds alias assumptions to the +``ptr_provenance`` of the memory instructions that depends on it. + +For this purpose, the ``llvm.provenance.noalias`` itself is also considered to be +a memory instruction and has its own ``ptr_provenance`` for the ``%p.addr`` +argument. + +A detailed description of these intrinsics and how the work is explained in +::doc::`Restrict and NoAlias Information in LLVM ` + + +.. _int_noalias_arg_guard: + +'``llvm.noalias.arg.guard``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. The return type and argument types are encoded +in ``XXX``. + +:: + + declare * @llvm.noalias.arg.guard.XXX(* %p, * %prov.p) + +Overview: +""""""""" + +The ``llvm.noalias.arg.guard`` intrinsic brings alias assumption properties that +are on the ``ptr_provenance`` path of a pointer back into the +computation path of that pointer. + +Arguments: +"""""""""" + +The first argument ``%p`` represents the computation path of the pointer. + +The second argument ``%prov.p`` represents the ``ptr_provenance`` path +of that pointer. + +Semantics: +"""""""""" + +The ``llvm.noalias.arg.guard`` is typically generated when a ``llvm.noalias`` +intrinsic is converted to a ``llvm.provenance.noalias``, but the pointer escapes +because it is used as an argument to a function or it is returned. + +It can typically be optimized away after inlining: +* When it is encountered on the computation path, it is assumed to return the +first argument ``%p``. + +When it is encountered on a ``ptr_provenance`` path, it is assumed to +return the second argument ``%prov.p``. + +A detailed description of these intrinsics and how the work is explained in +::doc::`Restrict and NoAlias Information in LLVM ` + + +.. _int_noalias_copy_guard: + +'``llvm.noalias.copy.guard``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. The return type and argument types are encoded +in ``XXX``. + +:: + + declare * @llvm.noalias.copy.guard.XXX(* %p.block, i8* %p.decl, + metadata !p.indices, metadata !p.scope) + +Overview: +""""""""" + +``llvm.noalias.copy.guard`` is inserted in the source pointer argument when a +block of memory that will be copied (either using ``llvm.memcpy`` or a +combination of ``load``/``store`` instructions) is associated to a variable +that contains at least one restrict pointer. This could be a ``struct`` that +contains one or more restrict member pointers, or an array of restrict pointers. + +The intrinsic returns the first argument. + +Arguments: +"""""""""" + +The first argument ``%p.block`` represents the block that will be copied. + +The second argument ``%p.decl`` refers to the ``llvm.noalias.decl`` that is +associated with the block. + +The third argument ``!p.indices`` refers to a metadata list of metadata. Each +entry refers to another metadata list of integers, describing the GEP path +that contains a restrict pointer. A -1 value indicates that any index value +is a match. See above for an example. + +Semantics: +"""""""""" + +The ``llvm.noalias.copy.guard`` provides extra restrict information about a +block of memory that is copied over. When the memory copy is optimized away, +they will still be able to match the pointer access to the correct restrict +information. + +A detailed description of these intrinsics and how the work is explained in +::doc::`Restrict and NoAlias Information in LLVM ` + Floating Point Environment Manipulation intrinsics -------------------------------------------------- Index: llvm/docs/NoAliasInfo.rst =================================================================== --- /dev/null +++ llvm/docs/NoAliasInfo.rst @@ -0,0 +1,1399 @@ +======================================== +Restrict and NoAlias Information in LLVM +======================================== + +.. contents:: + :local: + :depth: 2 + +Introduction +============ + +LLVM provides a number of mechanisms to annotate that two accesses will not +alias. This document describes the provenance annotations on pointers with the +``noalias`` intrinsics, and ``noalias`` metadata on memory instructions +(load/store). + +Together, they provide a means to decide if two memory instructions **will not +alias**, by looking at the pointer provenance and combining this with the active +scopes (specified by the ``noalias`` metadata) of the memory instructions. + +All of C99 restrict can be mapped onto these annotations, resulting in a +powerful mechanism to provide extra alias information. + + +Relation with C99 ``restrict`` +============================== + +The noalias infrastructure can be used to fully support *C99 restrict* [#R1]_: +restrict pointers as function arguments, as local variables, as struct members. +(See [#R2]_: iso-C99-n1256, 6.7.3.1 'Formal definition of restrict'). + +Modeling ``restrict`` requires two pieces of information for a memory +instruction: + +- the *depends on* relationship of the pointer path on a restrict + pointer (pointer provenance) +- the *visibility* of that restrict pointer to the memory instruction + +Every variable, that contains at least one restrict pointer, that is defined in +a function (function arguments and local variables), will get a noalias scope +that is associate d to this variable declaration. The ``!noalias`` metadata is +used to annotate every memory instruction in the function with the restrict +variables (noalias scopes) that are visible to that memory instruction. + +Each restrict variable also gets a ``@llvm.noalias.decl`` at the place in the +control flow where it is defined. This identifies if restrict scopes must be +duplicated or not when loops are transformed. + +Whenever a restrict pointer is read, a ``@llvm.noalias`` intrinsic is introduced +to indicate the dependency on a restrict pointer. This intrinsic depends on the +pointer value and on the address of the pointer. Different addresses represent +different restrict pointers. Different restrict pointers point to different sets +of objects. + +A struct can contain multiple restrict pointers. As such, a single variable +definition (single scope) can contain multiple restrict pointers. The addresses +of the pointers ensure that they can be differentiated. + +When a struct is copied using the internal ``@llvm.memcpy``, the ``@llvm.noalias`` +intrinsic cannot be used. The ``@llvm.noalias.copy.guard`` provides information +on what parts of the struct represent restrict pointers. This ensures that the +correct dependencies can be reconstructed when the ``@llvm.memcpy`` is optimized +away. + +When a pointer to a restrict pointer is dereferenced, there is no local scope +available. These restrict pointers are associated with an ``unknown function +scope``. It is sometimes possible to refine those scopes later to actual +variable definitions. + +.. _noaliasinfo_basic_mechanism: + +Basic Mechanism +=============== + +Describing the full set of intrinsics with all their arguments at once, might be +confusing and can make it difficult to understand. Therefore, we start with +explaining the basic technology. We then build upon it to add missing parts. + +Throughout the explanation, C99 and LLVM-IR code fragments are used to provide +examples. This does not mean that the provided infrastructure can only be used +for implementing C99 restrict. It just shows that at least C99 restrict can be +mapped onto it. Other provenance based alias annotations will likely map just as +well onto it, without (or with only small) adaptations to the provided +infrastructure. + + +Single ``noalias`` Scope +------------------------ + +Following code fragment: + +.. code-block:: C + + void foo(int *pA, int *pB, int i) { + int * restrict rpA = pA; + int * pX = &rpA[i]; + + *rpA = 42; // (1) based on rpA + *pB = 43; // (2) not based on rpA + *pX = 44; // (3) based on rpA + } + +contains one *restrict* pointer ``rpA``, one pointer ``pX`` depending on it, and +one pointer ``pB`` not depending on ``rpA``. Based on the C99 restrict +description, \*rpA and \*pX can alias with each other. They will not alias with +\*pB. + +In pseudo LLVM-IR code, this can be represented as: + +.. code-block:: llvm + + define void @foo(i32* %pA, i32* %pB, i64 %i) { + %rpA = tail call i32* @llvm.noalias(i32* %pA, metadata !2) + %arrayidx = getelementptr inbounds i32, i32* %pA, i64 %i + store i32 42, i32* %rpA, !noalias !2 ; (1) + store i32 43, i32* %pB, !noalias !2 ; (2) + store i32 44, i32* %arrayidx, !noalias !2 ; (3) + ret void + } + + ; MetaData + !2 = !{!3} ; contains a single scope: !3 + !3 = distinct !{!3, !4, !"foo: rpA"} ; this scope represents rpA + !4 = distinct !{!4, !"foo"} + +* Metadata !2 defines a list of a single scope ``!3`` that represents ``rpA`` +* The ``@llvm.noalias`` intrinsic is associated with the single scope ``!3`` in + ``metadata !2``. It indicates that accesses based on this pointer are depending + on this ``!3`` scope. They will not alias with accesses *not* depending on the + same ``!3`` scope, as long as the scope is visible to both accesses. +* For this example, the ``!3`` scope is visible to all three stores (``!noalias + !2`` annotation on the stores). Because of this: + + * ``(1)`` and ``(3)`` may alias to each other: ``%rpA`` and ``%arrayidx`` + depend on the same ``!3`` scope. + * ``(1)`` and ``(3)`` will not alias with ``(2)``: ``%pB`` does not depend on + the ``!3`` scope. + + +Multiple ``noalias`` Scopes +--------------------------- + +Let's extend the example: + +.. code-block:: C + + void foo(int *pA, int *pB, int *pC, int i) { + int * restrict rpA = pA; + int * pX = &rpA[i]; + + *rpA = 42; // (1) based on rpA + *pB = 43; // (2) not based on rpA + *pX = 44; // (3) based on rpA + { + int * restrict rpC = pC; + // rpA and rpC visible + + *rpA = 45; // (4) based on rpA + *pB = 46; // (5) not based on rpA nor rpC + *rpC = 47; // (6) based on rpC + } + } + +with following pseudo LLVM-IR code: + +.. code-block:: llvm + + define void @foo(i32* %pA, i32* %pB, i32* %pC, i64 %i) { + %rpA = tail call i32* @llvm.noalias(i32* %pA, metadata !2) ; rpA + %arrayidx = getelementptr inbounds i32, i32* %pA, i64 %i + %rpC = tail call i32* @llvm.noalias(i32* %pC, metadata !11) ; rpC + store i32 42, i32* %rpA, !noalias !2 ; (1) rpA + store i32 43, i32* %pB, !noalias !2 ; (2) rpA + store i32 44, i32* %arrayidx, !noalias !2 ; (3) rpA + store i32 45, i32* %rpA, !noalias !13 ; (4) rpA and rpC + store i32 46, i32* %pB, !noalias !13 ; (5) rpA and rpC + store i32 47, i32* %rpC, !noalias !13 ; (6) rpA and rpC + ret void + } + + ; MetaData + !2 = !{!3} ; single scope: rpA + !3 = distinct !{!3, !4, !"foo: rpA"} + !4 = distinct !{!4, !"foo"} + !11 = !{!12} ; single scope: rpC + !12 = distinct !{!12, !4, !"foo: rpC"} + !13 = !{!12, !3} ; scopes: rpA and rpC + +In this fragment: + +* ``%rpA`` is associated with scope ``!3`` +* ``%rpC`` is associated with scope ``!12`` +* ``(1)``, ``(2)`` and ``(3)`` only see ``rpA``. (scope ``!3``) +* ``(4)``, ``(5)`` and ``(6)`` see ``rpA`` and ``rpC`` (scopes ``!3`` and ``!12``) + +Following C99 restrict: + +* ``(4)``, ``(5)`` and ``(6)`` will not alias each other. +* ``(6)`` will not alias ``(3)``: + + * ``(6)`` is based on ``rpC``, which is visible to ``(6)``, but not to + ``(3)`` => no conclusion. + * ``(3)`` is based on ``rpA`` which is visible to both ``(6)`` and ``(3)`` => + will not alias + +* ``(6)`` might alias with ``(2)``: + + * ``rpC`` is visible to ``(6)``, but not to ``(2)``. + * There are no other dependencies for those accesses. + + +Location of the ``restrict`` Declaration +---------------------------------------- + +Some optimization passes need to know where a restrict variable has been +declared. Only when that information is known, they can perform the correct +transformations. + +One of those transformations is *loop unrolling*. When restrict is applicable +across iterations, the loop can be unrolled without extra changes. But when +restrict is only applicable inside a single iteration, care must be taken to +also duplicate the noalias scopes while duplicating the loop body. + +Following code example shows those two cases: + +.. code-block:: c + + void restrictInLoop(int *pA, int *pB, int *pC, long N) { + for (int i=0; i defines the ``object P``. + +Example A: + +.. code-block:: C + + int foo(int* pA, int* pB) { + int * restrict rpA=pA; + *rpA=42; + *pB=99; + return *rpA; + } + +And in pseudo LLVM-IR as how clang would produce it: + +.. code-block:: llvm + + define i32 @foo(i32* %pA, i32* %pB) { + %rpA.address = alloca i32* + %rpA.decl = call @llvm.noalias.decl %rpA.address, !metadata !10 ; declaration of a restrict pointer + store i32* %pA, i32** %rpA.address, !noalias !10 + %rpA = load i32*, i32** %rpA.address, !noalias !10 + %rpA.1 = i32* call @llvm.noalias %rpA, %rpA.decl, %rpA.address ; reading of a restrict pointer + store i32 42, i32* %rpA.1, !noalias !10 + store i32 99, i32* %pB, !noalias !10 + %1 = load i32, i32* %rpA.1, !noalias !10 + ret i32 %1 + } + +With this representation, we have enough information to decide whether two +load/stores are not aliasing, based on the ``noalias`` annotations. But, the +added intrinsics must block optimizations. Later on we will see how the +infrastructure is expanded to allow for optimizations. + +Summary: + +* ``%p.decl = @llvm.noalias.decl %p.alloc, metadata !Scope`` +* ``%p.val = @llvm.noalias %p, %p.decl, %p.addr`` + + +Pointer Provenance +------------------ + +In order to keep track of the dependency on the ``@llvm.noalias`` intrinsics, +but still allow most optimization passes to do their work, an extra optional +operand for ``load``/``store`` instruction is introduced: the ``ptr_provenance`` +operand. + +The idea is that the *pointer operand* is used for normal pointer +computations. The ``ptr_provenance`` operand is used to track ``noalias`` +related dependencies. Optimizations (like LSR) can modify the *pointer operand* +as they see fit. As long as the ``ptr_provenance operand`` is not touched, we +are still able to deduce the noalias related information. + +When an optimization introduces a ``load``/``store`` without keeping the +``ptr_provenance`` operand and the ``!noalias`` metadata, we fall back to the +fail-safe *worst case*. + +Although the actual pointer computations can be removed from the +``ptr_provenance``, it can still contain *PHI* nodes, *select* instructions and +*casts*. + +For clang, it is hard to track the usage of a pointer and it will not generate +the ``ptr_provenance`` operand. At LLVM-IR level, this is much easier. Because +of that the annotations exist in two states and a conversion pass is introduced: + +* Before *noalias propagation*: + + This state is produced by clang and sometimes by SROA. The ``@llvm.noalias`` + intrinsic is used in the computation path of the pointer. It is treated as a + mostly opaque intrinsic and blocks most optimizations. + + +* After *noalias propagation*: + + A *noalias propagation and conversion* pass is introduced: + + * ``@llvm.noalias`` intrinsics are converted into ``@llvm.provenance.noalias`` + intrinsics. + * their usage is removed from the main pointer computations of + ``load``/``store`` instructions and moved to the ``ptr_provenance`` operand. + * When a pointer depending on a ``@llvm.noalias`` intrinsic is passed as an + argument, returned from a function or stored into memory, a + ``@llvm.noalias.arg.guard`` is introduced. This combines the original + pointer computation with the provenance information. After inlining, it is + also used to propagate the noalias information to the ``load``/``store`` + instructions. + +So, we now have two extra intrinsics: + +* ``@llvm.provenance.noalias`` %prov.p, %p.decl, %p.addr + + * provides restrict information to a ``ptr_provenance`` operand + + * ``%prov.p``: tracks the provenance information associated with the pointer + value that was read. + * ``%p.decl`` refers to the ``@llvm.noalias.decl`` that is associated with the + restrict pointer. + * ``%p.addr``: represents the address of ``object P``. + +* ``@llvm.noalias.arg.guard %p, %prov.p`` + + * combines pointer and ``ptr_provenance`` information when a pointer value + with ``noalias`` dependencies escapes. It is normally used for function + arguments, returns, or stores to memory. + * ``%p`` tracks the pointer computation + * ``%prov.p`` tracks the provenance of the pointer. + +After noalias propagation and conversion, example A becomes: + +.. code-block:: llvm + + define i32 @foo(i32* %pA, i32* %pB) { + %rpA.address = alloca i32* + %rpA.decl = i8* call @llvm.noalias.decl i32* %rpA.address, !metadata !10 ; declaration of a restrict pointer + store i32* %pA, i32** %rpA.address, !noalias !10 + %rpA = load i32*, i32** %rpA.address, !noalias !10 + ; reading of a restrict pointer: + %prov.rpA.1 = i32* call @llvm.provenance.noalias i32* %rpA, i8* %rpA.decl, i32* %rpA.address + store i32 42, i32* %rpA, ptr_provenance i32* %prov.rpA.1, !noalias !10 + store i32 99, i32* %pB, !noalias !10 + %1 = load i32, i32* %rpA.1, !noalias !10 + ret i32 %1 + } + +Summary: + +* ``%p.decl = @llvm.noalias.decl %p.alloc, metadata !Scope`` +* ``%p.noalias = @llvm.noalias %p, %p.decl, %p.addr`` +* ``%prov.p = @llvm.provenance.noalias %prov.p.2, %p.decl, %p.addr`` +* ``%p.guard = @llvm.noalias.arg.guard %p, %prov.p`` + + +.. _noalias_vs_provenance_noalias: + +``@llvm.noalias`` vs ``@llvm.provenance.noalias`` +------------------------------------------------- + +The ``@llvm.noalias`` intrinsic is a convenience shortcut for the combination of +``@llvm.provenance.noalias``, which can only reside on the ptr_provenance path, +and ``@llvm.noalias.arg.guard``, which combines the normal pointer with the +ptr_provenance path: + +* This results in less initial code to be generated by ``clang``. +* It also helps during SROA when introducing ``noalias`` information for pointers + inside a struct. +* The noalias propagation and conversion pass depends on the property of + ``@llvm.provenance.noalias`` to only reside on the ``ptr_provenance`` path to + reduce the amount of work. + +.. code-block:: llvm + + ; Following: + %rpA = load i32*, i32** %rpA.address, !noalias !10 + %rpA.1 = i32* call @llvm.noalias %rpA, %rpA.decl, %rpA.address + store i32 42, i32* %rpA.1, !noalias !10 + + ; is a shortcut for: + %rpA = load i32*, i32** %rpA.address, !noalias !10 + %rpA.prov = i32* call @llvm.provenance.noalias %rpA, %rpA.decl, %rpA.address + %rpA.guard = i32* call @llvm.noalias.arg.guard %rpA, %rpA.prov + store i32 42, i32* %rpA.guard, !noalias !10 + + ; and after noalias propagation and conversion, this becomes: + %rpA = load i32*, i32** %rpA.address, !noalias !10 + %prov.rpA = i32* call @llvm.provenance.noalias %rpA, %rpA.decl, %rpA.address + store i32 42, i32* %rpA, ptr_provenance i32* %prov.rpA, !noalias !10 + + + +SROA and Stack optimizations +---------------------------- + +When SROA eliminates a local variable, we do not have an address for ``object P`` +anymore (the alloca is removed and ``%p.addr`` becomes ``null``). At that moment +we can only depend on the ``!Scope`` metadata to differentiate restrict +objects. For convenience, we also add this information to the ``@llvm.noalias`` +and ``@llvm.provenance.noalias`` intrinsics. + +It is also possible that a single variable declaration contains multiple +restrict pointers (think of a struct containing multiple restrict pointers, or +an array of restrict pointers). For correctness, SROA must introduce new scopes +when splitting it up. But cloning and adapting scopes can be very +expensive. Because of that, we introduce an extra *object ID* (``objId``) +parameter for ``@llvm.noalias.decl``, ``@llvm.noalias`` and +``llvm.provenance.noalias``. This can be thought of as the *offset in the +variable*. This allows us to differentiate *noalias* dependencies coming from +the same variable, but representing different *noalias* pointers. + +Summary: + +* ``%p.decl = @llvm.noalias.decl %p.alloc, i64 objId, metadata !Scope`` +* ``%p.noalias = @llvm.noalias %p, %p.decl, %p.addr, i64 objId, metadata !Scope`` +* ``%prov.p = @llvm.provenance.noalias %prov.p.2, %p.decl, %p.addr, i64 objId, metadata !Scope`` +* ``%p.guard = @llvm.noalias.arg.guard %p, %prov.p`` + +For alias analysis, this means that two ``@llvm.provenance.noalias`` intrinsics represent a +different ``object P0`` and, ``object P1``, if: + +* ``%p0.addr`` and ``%p1.addr`` are different +* or, ``objId0`` and ``objId1`` are different +* or, ``!Scope0`` and ``!Scope1`` are different + + +Optimizing a restrict pointer pointing to a restrict pointer +------------------------------------------------------------ + +Example: + +.. code-block:: C + + int * restrict * restrict ppA = ...; + int * restrict * restrict ppB = ...; + + **ppA=42; + **ppB=99; + return **ppA; // according to C99, 6.7.3.1 paragraph 4, **ppA and **ppB are not aliasing + +In order to allow this optimization, we also need to track the ``!noalias`` scope +when the ``@llvm.noalias`` intrinsic is introduced. The ``%p.addr`` parameter in the +``@llvm.provenance.noalias`` version will also get a ``ptr_provenance`` operand, +through the ``%prov.p.addr`` argument. + +In short, the ``@llvm.noalias`` and ``@llvm.provenance.noalias`` intrinsics are +treated as if they are a memory operation. + +Summary: + +* ``%p.decl = @llvm.noalias.decl %p.alloc, i64 objId, metadata !Scope`` +* ``%p.noalias = @llvm.noalias %p, %p.decl, %p.addr, i64 objId, metadata !Scope, !noalias !VisibleScopes`` +* ``%prov.p = @llvm.provenance.noalias %prov.p.2, %p.decl, %p.addr, %prov.p.addr, i64 objId, metadata !Scope, !noalias !VisibleScopes`` +* ``%p.guard = @llvm.noalias.arg.guard %p, %prov.p`` + +For alias analysis, this means that two ``@llvm.provenance.noalias`` intrinsics represent a +different ``object P0`` and ``object P1`` if: + +* ``%p0.addr`` and ``%p1.addr`` are different +* or, ``objId0`` and ``objId1`` are different +* or, ``!Scope0`` and ``!Scope1`` are different +* or we can prove that { ``%p0.addr``, ``%prov.p0.addr``, ``!VisibleScopes0`` } and + { ``%p1.addr``, ``%prov.p1.addr``, ``!VisibleScopes1`` } do not alias for both + intrinsics. (As if we treat each of the two ``@llvm.provenance.noalias`` as a + **store to ``%p.addr``** and we must prove that the two stores do not alias; + also see [#R8]_, question 2) + + +``Unknown function`` Scope +-------------------------- + +When the declaration of a restrict pointer is not visible, *C99, 6.7.3.1 +paragraph 2*, says that the pointer is assumed to start living from ``main``. + +This case can be handled by the ``unknown function`` scope, which is annotated +to the function itself. This can be treated as saying: the scope of this restrict +pointer starts somewhere outside this function. In such case, the +``@llvm.noalias`` and ``@llvm.provenance.noalias`` will not be associated with a +``@llvm.noalias.decl``. It is possible that after inlining, the scopes can be +refined to a declaration which became visible. + +For convenience, each function can have its own ``unknown function`` scope +specified by a ``noalias !UnknownScope`` metadata attribute on the function itself. + + +Aggregate Copies +---------------- + +Restrictness is introduced by *reading a restrict pointer*. It is not always +possible to add the necessary ``@llvm.noalias`` annotation when this is done. An +aggregate containing one or more restrict pointers can be copied with a single +``load``/``store` pair or a ``@llvm.memcpy``. This makes it hard to track when a +restrict pointer is copied over. As long as this is treated as an memory escape, +there is no issue. At the moment that the copy is optimized away, we must be +able to reconstruct the ``noalias`` dependencies for correctness. + +For this, a final intrinsic is introduced: ``@llvm.noalias.copy.guard``: + +* ``@llvm.noalias.copy.guard %p.addr, %p.decl, metadata !Indices, metadata !Scope`` + + * Guards a ``%p.addr`` object that is copied as a single aggregate or ``@llvm.memcpy`` + * ``%p.addr``: the object to guard + * ``%p.decl``: (when available), the ``@llvm.noalias.decl`` associated with the object + * ``!Indices``: this refers to a metadata list. Each element of the list + refers to a set of indices where a restrict pointer is located, similar to + the indices for a ``getelementptr``. + * ``!Scope``: the declaration scope of ``%p.decl`` + +This information allows *SROA* to introduce the needed ``@llvm.noalias`` intrinsics +when a struct is split up. + +Summary: + +* potential ``!noalias !UnknownScope`` annotation at function level +* ``%p.decl = @llvm.noalias.decl %p.alloc, i64 objId, metadata !Scope`` +* ``%p.noalias = @llvm.noalias %p, %p.decl, %p.addr, i64 objId, metadata !Scope, !noalias !VisibleScopes`` +* ``%prov.p = @llvm.provenance.noalias %prov.p.2, %p.decl, %p.addr, %prov.p.addr, i64 objId, metadata !Scope, !noalias !VisibleScopes`` +* ``%p.guard = @llvm.noalias.arg.guard %p, %prov.p`` +* ``%p.addr.guard = @llvm.noalias.copy.guard %p.addr, %p.decl, metadata !Indices, metadata !Scope, !noalias !VisibleScopes`` + +Optimization passes +------------------- + +For correctness, some optimization passes must be aware of the *noalias intrinsics*: +inlining [#R7]_, unrolling [#R6]_, loop rotation, ... Whenever a body is duplicated that +contains a ``@llvm.noalias.decl``, it must be decided how that duplication must be done. +Sometimes new unique scopes must be introduced, sometimes not. + +Other optimization passes can perform better by knowing about the ``ptr_provenance``: when +new ``load``/``store`` instructions are introduced, adding ``ptr_provenance`` +information can result in better alias analysis for those instructions. + +It is possible that an optimization pass is doing a wrong optimization, by doing +a transformation that omits the ``ptr_provenance`` operand, but keeps the +``!noalias`` information. This can happen when the ``!noalias`` metadata is +copied directly, instead of using ``AAMetadata`` and +``getAAMetadata/setAAMetadata``: + +.. code-block:: C + + AAMDNodes AAMD; + OldLoad->getAAMetadata(AAMD); + NewLoad->setAAMetadata(AAMD); + + // only do this if it is safe to copy over the 'ptr_provenance' info + // The !noalias info will then also be copied over + NewLoad->setAAMetadataNoAliasProvenance(AAMD); + +Possible Future Enhancements +---------------------------- + +* c++ alias_set + +With this framework in place, it should be easy to extend it to support the +*alias_set* proposal [#R3]_. This can be done by tracking a separate *universe +object*, instead of *object P*. + + +Detailed Description +==================== + +This section gives a detailed description of the various intrinsics and +metadata. + +``!noalias`` Scope Metadata +--------------------------- + +The ``!noalias`` metadata consists of a *list of scopes*. Each scope is also +associated to the function to which it belongs. + +.. code-block:: llvm + + ; MetaData + !2 = !{!3} ; single scope: rpA + !3 = distinct !{!3, !4, !"foo: rpA"} ; variable 'rpA' + !4 = distinct !{!4, !"foo"} ; function 'foo' + !5 = !{!6} + !6 = distinct !{!6, !7, !"foo: unknown scope"} + !7 = distinct !{!7, !"foo"} + !11 = !{!12} ; single scope: rpC + !12 = distinct !{!12, !4, !"foo: rpC"} ; variable 'rpC' + !13 = !{!12, !3} ; multiple scopes: rpA and rpC + +This structure is used in following places: + +* as a single scope: + + * used as *metavalue* argument by ``@llvm.noalias.decl``, ``@llvm.noalias``, + ``@llvm.provenance.noalias``, ``@llvm.noalias.copy.guard``. (``!2, !11``) to + describe the scope that is associated with the noalias intrinsic. + * used as ``!noalias`` metadata on a function to describe the ``unknown + function scope``. (``!5``) + +* as one or more scopes: + + * used as ``!noalias`` metadata describingthe *visible scopes* on memory + instructions (``load``/``store``) and ``@llvm.noalias`` and + ``@llvm.provenance.noalias`` intrinsics. + +.. note:: The ``Unknown Function Scope`` is a special scope that is attached + through ``!noalias`` metadata on a function defintion. It identifies + the scope that is used for *noalias* pointers for which the + declaration is not known. + + +``ptr_provenance`` path +----------------------- + +The ``ptr_provenance`` path is reserved for tracking *noalias* information that +is associated to pointers. Value computations should be omitted as much as +possible. + +For memory instructions, this means that the actual pointer value and the +provenance information can be separated. This allows optimization passes to +rewrite the pointer computation and still keep the correct provenance information. + +A ``ptr_provenance`` path normally starts: + +* with the ``ptr_provenance`` operand of a ``load``/``store`` instruction +* with the ``ptr_provenance`` operand of the ``@llvm.noalias.arg.guard`` + intrinsic +* with the ``ptr.provenance`` operand of the ``@llvm.provenance.noalias`` + intrinsic + +As the ``@llvm.provenance.noalias``, can only be part of a ``ptr_provenance`` +path, its ``%p`` operand is also part of the ``ptr_provenance`` path. + +Although all uses of a ``@llvm.provenance.noalias`` must be on a +``ptr_provenance`` path, following the *based on* path must end at a normal +pointer value. This can for example be the input argument of a +function. Optimizations like inlining can provide extra information for such a +pointer. + +Examples +-------- + +This section contains some examples that are used in the description of the +intrinsics. + +.. _noaliasinfo_local_restrict: + +Example A: local restrict +""""""""""""""""""""""""" + +.. _noaliasinfo_local_restrict_C: + +C99 code with local restrict variables: + +.. code-block:: C + + int foo(int * pA, int i, int *pC) { + int * restrict rpA = pA; + int * restrict rpB = pA+i; + + // The three accesses are promised to not alias each other + *rpA = 10; + *rpB = 20; + *pC = 30; + + return *rpA+*rpB+*pC; + } + +.. _noaliasinfo_local_restrict_llvm_0: + +LLVM-IR code as produced by clang: + +.. code-block:: llvm + + ; Function Attrs: nounwind + define dso_local i32 @foo(i32* %pA, i32 %i, i32* %pC) #0 { + entry: + %pA.addr = alloca i32*, align 4 + %i.addr = alloca i32, align 4 + %pC.addr = alloca i32*, align 4 + %rpA = alloca i32*, align 4 + %rpB = alloca i32*, align 4 + store i32* %pA, i32** %pA.addr, align 4, !tbaa !3, !noalias !7 + store i32 %i, i32* %i.addr, align 4, !tbaa !11, !noalias !7 + store i32* %pC, i32** %pC.addr, align 4, !tbaa !3, !noalias !7 + %0 = bitcast i32** %rpA to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #4, !noalias !7 + %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** %rpA, i64 0, metadata !13), !noalias !7 + %2 = load i32*, i32** %pA.addr, align 4, !tbaa !3, !noalias !7 + store i32* %2, i32** %rpA, align 4, !tbaa !3, !noalias !7 + %3 = bitcast i32** %rpB to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* %3) #4, !noalias !7 + %4 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** %rpB, i64 0, metadata !14), !noalias !7 + %5 = load i32*, i32** %pA.addr, align 4, !tbaa !3, !noalias !7 + %6 = load i32, i32* %i.addr, align 4, !tbaa !11, !noalias !7 + %add.ptr = getelementptr inbounds i32, i32* %5, i32 %6 + store i32* %add.ptr, i32** %rpB, align 4, !tbaa !3, !noalias !7 + %7 = load i32*, i32** %rpA, align 4, !tbaa !3, !noalias !7 + %8 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %7, i8* %1, i32** %rpA, i64 0, metadata !13), + !tbaa !3, !noalias !7 + store i32 10, i32* %8, align 4, !tbaa !11, !noalias !7 + %9 = load i32*, i32** %rpB, align 4, !tbaa !3, !noalias !7 + %10 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %9, i8* %4, i32** %rpB, i64 0, metadata !14), + !tbaa !3, !noalias !7 + store i32 20, i32* %10, align 4, !tbaa !11, !noalias !7 + %11 = load i32*, i32** %pC.addr, align 4, !tbaa !3, !noalias !7 + store i32 30, i32* %11, align 4, !tbaa !11, !noalias !7 + %12 = load i32*, i32** %rpA, align 4, !tbaa !3, !noalias !7 + %13 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %12, i8* %1, i32** %rpA, i64 0, metadata !13), + !tbaa !3, !noalias !7 + %14 = load i32, i32* %13, align 4, !tbaa !11, !noalias !7 + %15 = load i32*, i32** %rpB, align 4, !tbaa !3, !noalias !7 + %16 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %15, i8* %4, i32** %rpB, i64 0, metadata !14), + !tbaa !3, !noalias !7 + %17 = load i32, i32* %16, align 4, !tbaa !11, !noalias !7 + %add = add nsw i32 %14, %17 + %18 = load i32*, i32** %pC.addr, align 4, !tbaa !3, !noalias !7 + %19 = load i32, i32* %18, align 4, !tbaa !11, !noalias !7 + %add1 = add nsw i32 %add, %19 + %20 = bitcast i32** %rpB to i8* + call void @llvm.lifetime.end.p0i8(i64 4, i8* %20) #4 + %21 = bitcast i32** %rpA to i8* + call void @llvm.lifetime.end.p0i8(i64 4, i8* %21) #4 + ret i32 %add1 + } + + ; .... + + !7 = !{!15, !17} + !13 = !{!15} + !14 = !{!17} + !15 = distinct !{!15, !16, !"foo: rpA"} + !16 = distinct !{!16, !"foo"} + !17 = distinct !{!17, !16, !"foo: rpB"} + +.. _noaliasinfo_local_restrict_llvm_1: + +LLVM-IR code during optimization: stack objects have already been optimized +away, ``@llvm.noalias`` has been converted into ``@llvm.provenance.noalias`` and +propagated to the ``ptr_provenance`` path. + +.. code-block:: llvm + + ; Function Attrs: nounwind + define dso_local i32 @foo(i32* %pA, i32 %i, i32* %pC) #0 { + entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !3) + %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !6) + %add.ptr = getelementptr inbounds i32, i32* %pA, i32 %i + %2 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %pA, i8* %0, + i32** null, i32** undef, i64 0, metadata !3), !tbaa !8, !noalias !12 + store i32 10, i32* %pA, ptr_provenance i32* %2, align 4, !tbaa !13, !noalias !12 + %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %add.ptr, i8* %1, + i32** null, i32** undef, i64 0, metadata !6), !tbaa !8, !noalias !12 + store i32 20, i32* %add.ptr, ptr_provenance i32* %3, align 4, !tbaa !13, !noalias !12 + store i32 30, i32* %pC, align 4, !tbaa !13, !noalias !12 + %4 = load i32, i32* %pA, ptr_provenance i32* %2, align 4, !tbaa !13, !noalias !12 + %5 = load i32, i32* %add.ptr, ptr_provenance i32* %3, align 4, !tbaa !13, !noalias !12 + %add = add nsw i32 %4, %5 + %add1 = add nsw i32 %add, 30 + ret i32 %add1 + } + + ; ... + + !3 = !{!4} + !4 = distinct !{!4, !5, !"foo: rpA"} + !5 = distinct !{!5, !"foo"} + !6 = !{!7} + !7 = distinct !{!7, !5, !"foo: rpB"} + !8 = !{!9, !9, i64 0} + !12 = !{!4, !7} + +.. _noaliasinfo_local_restrict_llvm_2: + +And LLVM-IR code after optimizations: alias analysis found the the stores do not +alias to each other and the values have been propagated. + +.. code-block:: llvm + + ; Function Attrs: nounwind + define dso_local i32 @foo(i32* nocapture %pA, i32 %i, i32* nocapture %pC) local_unnamed_addr #0 { + entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !3) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !6) + %add.ptr = getelementptr inbounds i32, i32* %pA, i32 %i + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %pA, i8* %0, + i32** null, i32** undef, i64 0, metadata !3), !tbaa !8, !noalias !12 + store i32 10, i32* %pA, ptr_provenance i32* %2, align 4, !tbaa !13, !noalias !12 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull %add.ptr, i8* %1, + i32** null, i32** undef, i64 0, metadata !6), !tbaa !8, !noalias !12 + store i32 20, i32* %add.ptr, ptr_provenance i32* %3, align 4, !tbaa !13, !noalias !12 + store i32 30, i32* %pC, align 4, !tbaa !13, !noalias !12 + ret i32 60 + } + + ; .... + + !3 = !{!4} + !4 = distinct !{!4, !5, !"foo: rpA"} + !5 = distinct !{!5, !"foo"} + !6 = !{!7} + !7 = distinct !{!7, !5, !"foo: rpB"} + + !12 = !{!4, !7} + +.. _noaliasinfo_pass_restrict: + +Example B: pass a restrict pointer +"""""""""""""""""""""""""""""""""" + +.. _noaliasinfo_pass_restrict_C: + +C99 code with local restrict variables: + +.. code-block:: C + + int fum(int * p); + + int foo(int * pA) { + int * restrict rpA = pA; + *rpA = 10; + + return fum(rpA); + } + + +.. _noaliasinfo_pass_restrict_llvm_0: + +LLVM-IR code as produced by clang: + +.. code-block:: llvm + + ; Function Attrs: nounwind + define dso_local i32 @foo(i32* %pA) #0 { + entry: + %pA.addr = alloca i32*, align 4 + %rpA = alloca i32*, align 4 + store i32* %pA, i32** %pA.addr, align 4, !tbaa !3, !noalias !7 + %0 = bitcast i32** %rpA to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #5, !noalias !7 + %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** %rpA, i64 0, metadata !7), !noalias !7 + %2 = load i32*, i32** %pA.addr, align 4, !tbaa !3, !noalias !7 + store i32* %2, i32** %rpA, align 4, !tbaa !3, !noalias !7 + %3 = load i32*, i32** %rpA, align 4, !tbaa !3, !noalias !7 + %4 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %3, i8* %1, i32** %rpA, i64 0, metadata !7), + !tbaa !3, !noalias !7 + store i32 10, i32* %4, align 4, !tbaa !10, !noalias !7 + %5 = load i32*, i32** %rpA, align 4, !tbaa !3, !noalias !7 + %6 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %5, i8* %1, i32** %rpA, i64 0, metadata !7), + !tbaa !3, !noalias !7 + %call = call i32 @fum(i32* %6), !noalias !7 + %7 = bitcast i32** %rpA to i8* + call void @llvm.lifetime.end.p0i8(i64 4, i8* %7) #5 + ret i32 %call + } + + +.. _noaliasinfo_pass_restrict_llvm_1: + +And LLVM-IR code after optimizations: stack objects have been optimized +away; ``@llvm.noalias`` has been converted into ``@llvm.provenance.noalias`` and +propagated to the ``ptr_provenance`` path. A ``@llvm.noalias.arg.guard`` has +been introduced to combine the ``ptr_provenance`` and the pointer value before +passing it to ``@fum``. + +.. code-block:: llvm + + ; Function Attrs: nounwind + define dso_local i32 @foo(i32* %pA) local_unnamed_addr #0 { + entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !3) + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %pA, i8* %0, + i32** null, i32** undef, i64 0, metadata !3), !tbaa !6, !noalias !3 + store i32 10, i32* %pA, ptr_provenance i32* %1, align 4, !tbaa !10, !noalias !3 + %.guard.guard.guard.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* nonnull %pA, i32* %1) + %call = tail call i32 @fum(i32* nonnull %.guard.guard.guard.guard) #4, !noalias !3 + ret i32 %call + } + +``@llvm.noalias.decl`` Intrinsic +-------------------------------- + +Syntax: +""""""" + +.. code-block:: llvm + + %p.decl = + i8* call @llvm.noalias.decl + T* %p.alloca, i64 objId, metadata !Scope + + +Overview: +""""""""" + +Identify where in the control flow a *noalias* declaration happened. + +Arguments: +"""""""""" + +* ``%p.alloca``: points to the ``alloca`` to which this declaration is + associated. Or ``null`` when the ``alloca`` was optimized away. +* ``objId``: an ID that is associated to this declaration. *SROA* treats this as + an offset wrt to the original ``alloca``. +* ``!Scope``: a single scope that is associated with this declaration. + +Semantics: +"""""""""" + +Identify where in the control flow a *noalias* declaration happened. When this +intrinsic is duplicated, care must be taken to decide if the associated +``!Scope`` metadata must be duplicated as well (in case of loop unrolling) or +not (in case of code hoisting over then/else paths). + +The function returns a handle to the *noalias* declaration. + +Examples: +========= +See :ref:`Example A: local restrict` and +:ref:`Example B: pass a restrict pointer`. + + +``@llvm.noalias`` Intrinsic +--------------------------- + +Syntax: +""""""" + +.. code-block:: llvm + + %p.noalias = + T* call @llvm.noalias + T* %p, i8* %p.decl, + T** %p.addr, i64 objId, metadata !Scope, + !noalias !VisibleScopes + +Overview: +""""""""" + +Adds *noalias* provenance information to a pointer. + +Arguments: +"""""""""" + +* ``%p``: the original value of the pointer. +* ``%p.decl``: the associated *noalias* declaration (or ``null`` if the + declaration is not available). +* ``%p.addr``: the address of the pointer. +* ``objId``: the ID that is associated to the noalisa declaration. *SROA* treats + this as an offset wrt to the original ``alloca``. +* ``!Scope``: a single scope that is associated with the noalias declaration. +* ``!VisibleScopes``: the scopes related to *noalias* declarations that are + visible to location in the control flow where the noalias pointer is read from + memory. + +Semantics: +"""""""""" + +Adds *noalias* provenance information so that all memory instructions that +depend on ``%p.noalias`` are known to be based on a pointer with extra *noalias* +info. This is a mostly opaque intrinsic for optimizations. In order to not block +optimizations, it will be converted into a ``@llvm.provenance.noalias`` and +moved to the ``ptr_provenance`` path of memory instructions. + +When a ``%p.decl`` is available, following arguments must match the ones in that +declaration: ``objId``, ``!Scope``. + +When ``!Scope`` points to the *unknown function scope*, ``%p.decl`` must be +``null``. + +.. note:: + ``@llvm.noalias`` can be seen as a shortcut for ``@llvm.provenance.noalias`` + and ``@llvm.noalias.arg.guard``. See + :ref:`@llvm.noalias vs @llvm.provenance.noalias`. + +Examples: +========= +See :ref:`Example A: local restrict` and +:ref:`Example B: pass a restrict pointer`. + + + +``@llvm.provenance.noalias`` Intrinsic +-------------------------------------- + +Syntax: +""""""" + +.. code-block:: llvm + + %prov.p = + T* call @llvm.provenance.noalias + T* %p, i8* %p.decl, + T** %p.addr, T** %prov.p.addr, i64 objId, metadata !Scope, + !noalias !VisibleScopes`` + +Overview: +""""""""" + +Adds *noalias* provenance information to a pointer. This version, which is +similar to ``@llvm.noalias``, must only be found on the ``ptr_provenance`` path. + +Arguments: +"""""""""" + +* ``%p``: the original value of the pointer, or a depending + ``@llvm.provenance.noalias``. +* ``%p.decl``: the associated *noalias* declaration (or ``null`` if the + declaration is not available). +* ``%p.addr``: the address of the pointer. +* ``%prov.p.addr``: the ``ptr_provenance`` associated to ``%p.addr``. If this is + ``Undef``, the original ``%p.addr`` must be followed. +* ``objId``: the ID that is associated to the noalisa declaration. *SROA* treats + this as an offset wrt to the original ``alloca``. +* ``!Scope``: a single scope that is associated with the noalias declaration. +* ``!VisibleScopes``: the scopes related to *noalias* declarations that are + visible to location in the control flow where the noalias pointer is read from + memory. + +Semantics: +"""""""""" + +Adds *noalias* provenance information to a pointer. This is similar to +``@llvm.noalias``, but this version must only be found on the ``ptr_provenance`` +path of memory instructions or of the ``@llvm.noalias.arg.guard`` intrinsic. + +It can also be found on the path of the ``%prov.p.addr`` and on the ``%p`` +arguments of another ``@llvm.provenance.noalias`` intrinsic. + +When a ``%p.decl`` is available, following arguments must match the ones in that +declaration: ``objId``, ``!Scope``. + +When ``!Scope`` points to the *unknown function scope*, ``%p.decl`` must be +``null``. + +Examples: +========= +See :ref:`Example A: local restrict` and +:ref:`Example B: pass a restrict pointer`. + + +``@llvm.noalias.arg.guard`` Intrinsic +------------------------------------- + +Syntax: +""""""" + +.. code-block:: llvm + + %p.guard = + T* call @llvm.noalias.arg.guard + T* %p, T* %prov.p + +Overview: +""""""""" + +Combines the value of a pointer with its *noalias* provenance information. + +Arguments: +"""""""""" + +* ``%p``: the value of the pointer +* ``%prov.p``: the provenance information associated to ``%p`` + + +Semantics: +"""""""""" + +Combines the value of a pointer with its *noalias* provenance information. This +is normally introduced when converting ``@llvm.noalias`` into +``@llvm.provenance.noalias`` and the pointer is passed as a function +argument, returned from a function or stored to memory. This intrinsic ensures +that at a later time (after inlining and/or other optimizations), the provenance +information can be propagated to the memory instructions depending on the guard. + +Examples: +========= +See :ref:`Example B: pass a restrict pointer`. + + +``@llvm.noalias.copy.guard`` Intrinsic +-------------------------------------- + +Syntax: +""""""" + +.. code-block:: llvm + + %p.addr.guard = + T* call @llvm.noalias.copy.guard + T* %p.addr, i8* %p.decl, + metadata !Indices, + metadata !Scope, + !noalias !VisibleScopes + +Overview: +""""""""" + +Annotates that the memory block pointed to by ``%p.addr`` contains *noalias +annotated pointers* (restrict pointers). + +Arguments: +"""""""""" + +* ``%p.addr``: points to the block of memory that will be copied +* ``%p.decl``: the associated *noalias* declaration (or ``null`` if the + declaration is not available). +* ``!Indices``: the set of indices, describing on what locations a *noalias* + pointer can be found. +* ``!Scope``: a single scope that is associated with the noalias declaration. +* ``!VisibleScopes``: the scopes related to *noalias* declarations that are + visible to location in the control flow where the noalias pointer is read from + memory. + +Semantics: +"""""""""" + +Annotates that the memory block pointed to by ``%p.addr`` contains *noalias +annotated pointers* (restrict pointers). The ``!Indices`` indicate where in +memory the *noalias* pointers are located. + +When a block copy (aggregate load/store or ``@llvm.memcpy``) uses +``%p.addr.guard`` as a source, *SROA* is able to reconstruct the implied +``@llvm.noalias`` intrinsics. This ensure that the *noalias* information for +those pointers is tracked. + +When a ``%p.decl`` is available, the ``!Scope`` argument must match the one in +that declaration. + +When ``!Scope`` points to the *unknown function scope*, ``%p.decl`` must be +``null``. + + +``!Indices`` points to a list of metadata. Each entry in that list contains a +set of ``i32`` values, corresponding to the indices that would be past to +``getelementptr`` to retrieve a field in the struct. When the ``i32`` value is +**-1**, it indicates that any possible value should be checked (0, 1, 2, ...), +as long as the resulting address fits the size of the memory copy. + +Examples: +""""""""" + +Code example with a ``llvm.noalias.copy.guard``: + +* Note the **-1** to represent ``a[i]`` in the indices of ``!15``. +* After optimization, the ``alloca`` is gone. The ``llvm.memcpy`` is also gone, + but the remaining dependency on restrict pointers is kept in the + ``llvm.noalias.provenance``. Two are needed for this example: one related to + the declaration of ``struct B tmp``. One related to the ``unknown function + scope``. + +.. code-block:: C + + struct B { + int * restrict p; + struct A { + int m; + int * restrict p; + } a[5]; + }; + + + void FOO(struct B* b) { + struct B tmp = *b; + + *tmp.a[1].p=32; + } + +Results in following code: + +.. code-block:: llvm + + %struct.B = type { i32*, [5 x %struct.A] } + %struct.A = type { i32, i32* } + + ; Function Attrs: nounwind + define dso_local void @FOO(%struct.B* %b) #0 !noalias !3 { + entry: + %b.addr = alloca %struct.B*, align 4 + %tmp = alloca %struct.B, align 4 + store %struct.B* %b, %struct.B** %b.addr, align 4, !tbaa !6, !noalias !10 + %0 = bitcast %struct.B* %tmp to i8* + call void @llvm.lifetime.start.p0i8(i64 44, i8* %0) #5, !noalias !10 + %1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.Bs.i64(%struct.B* %tmp, i64 0, metadata !12), + !noalias !10 + %2 = load %struct.B*, %struct.B** %b.addr, align 4, !tbaa !6, !noalias !10 + %3 = call %struct.B* @llvm.noalias.copy.guard.p0s_struct.Bs.p0i8(%struct.B* %2, + i8* null, metadata !13, metadata !3) + %4 = bitcast %struct.B* %tmp to i8* + %5 = bitcast %struct.B* %3 to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %4, i8* align 4 %5, i32 44, i1 false), + !tbaa.struct !16, !noalias !10 + %a = getelementptr inbounds %struct.B, %struct.B* %tmp, i32 0, i32 1 + %arrayidx = getelementptr inbounds [5 x %struct.A], [5 x %struct.A]* %a, i32 0, i32 1 + %p = getelementptr inbounds %struct.A, %struct.A* %arrayidx, i32 0, i32 1 + %6 = load i32*, i32** %p, align 4, !tbaa !18, !noalias !10 + %7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %6, + i8* %1, i32** %p, i64 0, metadata !12), !tbaa !18, !noalias !10 + store i32 32, i32* %7, align 4, !tbaa !21, !noalias !10 + %8 = bitcast %struct.B* %tmp to i8* + call void @llvm.lifetime.end.p0i8(i64 44, i8* %8) #5 + ret void + } + + ... + + !3 = !{!4} + !4 = distinct !{!4, !5, !"FOO: unknown scope"} + !5 = distinct !{!5, !"FOO"} + !10 = !{!11, !4} + !11 = distinct !{!11, !5, !"FOO: tmp"} + !12 = !{!11} + !13 = !{!14, !15} + !14 = !{i32 -1, i32 0} + !15 = !{i32 -1, i32 1, i32 -1, i32 1} + +And after optimizations: + +.. code-block:: llvm + + ; Function Attrs: nounwind + define dso_local void @FOO(%struct.B* nocapture %b) local_unnamed_addr #0 !noalias !3 { + entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 16, metadata !6) + %tmp.sroa.69.0..sroa_idx10 = getelementptr inbounds %struct.B, %struct.B* %b, i32 0, i32 1, i32 1, i32 1 + %tmp.sroa.69.0.copyload = load i32*, i32** %tmp.sroa.69.0..sroa_idx10, align 4, !tbaa.struct !8, !noalias !14 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %tmp.sroa.69.0.copyload, + i8* null, i32** nonnull %tmp.sroa.69.0..sroa_idx10, i32** undef, i64 0, metadata !3) + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %1, + i8* %0, i32** null, i32** undef, i64 16, metadata !6), !tbaa !15, !noalias !14 + store i32 32, i32* %tmp.sroa.69.0.copyload, ptr_provenance i32* %2, align 4, !tbaa !18, !noalias !14 + ret void + } + + ... + + !3 = !{!4} + !4 = distinct !{!4, !5, !"FOO: unknown scope"} + !5 = distinct !{!5, !"FOO"} + !6 = !{!7} + !7 = distinct !{!7, !5, !"FOO: tmp"} + + +Other usages of ``noalias`` inside LLVM +======================================= + + +``noalias`` attribute on parameters or function +----------------------------------------------- + +This indicates that memory locations accessed via pointer values +:ref:`based ` on the argument or return value are not also +accessed, during the execution of the function, via pointer values not +*based* on the argument or return value. + +See :ref:`noalias attribute` + +``noalias`` and ``alias.scope`` Metadata +---------------------------------------- + +``noalias`` and ``alias.scope`` metadata provide the ability to specify generic +noalias memory-access sets. + +See :ref:`noalias and alias.scope Metadata ` + +The usage of this construct is not recommended, as it can result in wrong code +when inlining and loop unrolling optimizations are applied. + + +References +========== + +.. rubric:: References + +.. [#R1] https://en.wikipedia.org/wiki/Restrict +.. [#R2] WG14 N1256: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf (Chapter 6.7.3.1 Formal definition of restrict) +.. [#R3] WG21 N4150: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4150.pdf +.. [#R4] https://reviews.llvm.org/D9375 Hal Finkel's local restrict patches +.. [#R5] https://bugs.llvm.org/show_bug.cgi?id=39240 "clang/llvm looses restrictness, resulting in wrong code" +.. [#R6] https://bugs.llvm.org/show_bug.cgi?id=39282 "Loop unrolling incorrectly duplicates noalias metadata" +.. [#R7] https://www.godbolt.org/z/cUk6To "testcase showing that LLVM-IR is not able to differentiate if restrict is done inside or outside the loop" +.. [#R8] DR294: http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_294.htm +.. [#R9] WG14 N2250: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2260.pdf Clarifying the restrict Keyword v2 +.. [#R10] RFC: Full 'restrict' support in LLVM https://lists.llvm.org/pipermail/llvm-dev/2019-October/135672.html Index: llvm/docs/UserGuides.rst =================================================================== --- llvm/docs/UserGuides.rst +++ llvm/docs/UserGuides.rst @@ -48,6 +48,7 @@ JITLink NewPassManager NVPTXUsage + NoAliasInfo Phabricator Passes ReportingGuide @@ -131,6 +132,10 @@ Information on how to write a new alias analysis implementation or how to use existing analyses. +:doc:`NoAliasInfo` + Information on how provenance based alias analysis, used to implement C99 + restrict, works. + :doc:`MemorySSA` Information about the MemorySSA utility in LLVM, as well as how to use it. Index: llvm/include/llvm-c/Core.h =================================================================== --- llvm/include/llvm-c/Core.h +++ llvm/include/llvm-c/Core.h @@ -282,7 +282,8 @@ LLVMInlineAsmValueKind, LLVMInstructionValueKind, - LLVMPoisonValueValueKind + LLVMPoisonValueValueKind, + LLVMUnknownProvenanceValueKind } LLVMValueKind; typedef enum { @@ -1902,6 +1903,19 @@ */ LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty); +/** + * Determine whether a value instance is unknown_provenance. + * + * @see llvm::UnknownProvenance + */ +LLVMBool LLVMIsUnknownProvenance(LLVMValueRef Val); + +/** + * Obtain a constant that is an constant pointer pointing to unknown_provenance + * for a specified type. + */ +LLVMValueRef LLVMGetUnknownProvenance(LLVMTypeRef Ty); + /** * @defgroup LLVMCCoreValueConstantScalar Scalar constants * Index: llvm/include/llvm/Analysis/BasicAliasAnalysis.h =================================================================== --- llvm/include/llvm/Analysis/BasicAliasAnalysis.h +++ llvm/include/llvm/Analysis/BasicAliasAnalysis.h @@ -53,6 +53,7 @@ AssumptionCache &AC; DominatorTree *DT; PhiValues *PV; + unsigned RecurseLevel = 0; public: BasicAAResult(const DataLayout &DL, const Function &F, @@ -150,9 +151,9 @@ const Value *V2, LocationSize V2Size, AAQueryInfo &AAQI); - AliasResult aliasCheck(const Value *V1, LocationSize V1Size, - const Value *V2, LocationSize V2Size, - AAQueryInfo &AAQI); + AliasResult aliasCheck(const Value *V1, LocationSize V1Size, const Value *V2, + LocationSize V2Size, AAQueryInfo &AAQI, + bool StripNoAlias); AliasResult aliasCheckRecursive(const Value *V1, LocationSize V1Size, const Value *V2, LocationSize V2Size, Index: llvm/include/llvm/Analysis/MemoryLocation.h =================================================================== --- llvm/include/llvm/Analysis/MemoryLocation.h +++ llvm/include/llvm/Analysis/MemoryLocation.h @@ -16,6 +16,7 @@ #define LLVM_ANALYSIS_MEMORYLOCATION_H #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/Optional.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/TypeSize.h" @@ -216,6 +217,10 @@ /// The address of the start of the location. const Value *Ptr; + /// The provenance of the location. A nullptr or a ConstantPointerNull + /// indicate that the provenance can be from anywhere. + const Value *PtrProvenance = nullptr; + /// The maximum size of the location, in address-units, or /// UnknownSize if the size is not known. /// @@ -229,7 +234,14 @@ /// member is null if that kind of information is unavailable). AAMDNodes AATags; - void print(raw_ostream &OS) const { OS << *Ptr << " " << Size << "\n"; } + void print(raw_ostream &OS) const { + OS << *Ptr; + if (PtrProvenance) + OS << "(" << *PtrProvenance << ") "; + else + OS << "(nullptr) "; + OS << Size << "\n"; + } /// Return a location with information about the memory reference by the given /// instruction. @@ -283,11 +295,17 @@ } MemoryLocation() - : Ptr(nullptr), Size(LocationSize::beforeOrAfterPointer()), AATags() {} + : Ptr(nullptr), PtrProvenance(nullptr), + Size(LocationSize::beforeOrAfterPointer()), AATags() {} explicit MemoryLocation(const Value *Ptr, LocationSize Size, const AAMDNodes &AATags = AAMDNodes()) - : Ptr(Ptr), Size(Size), AATags(AATags) {} + : Ptr(Ptr), PtrProvenance(Ptr), Size(Size), AATags(AATags) {} + + explicit MemoryLocation(const Value *Ptr, const Value *PtrProvenance, + LocationSize Size, + const AAMDNodes &AATags = AAMDNodes()) + : Ptr(Ptr), PtrProvenance(PtrProvenance), Size(Size), AATags(AATags) {} MemoryLocation getWithNewPtr(const Value *NewPtr) const { MemoryLocation Copy(*this); @@ -295,6 +313,12 @@ return Copy; } + MemoryLocation getWithNewPtrProvenance(const Value *NewPtrProvenance) const { + MemoryLocation Copy(*this); + Copy.PtrProvenance = NewPtrProvenance; + return Copy; + } + MemoryLocation getWithNewSize(LocationSize NewSize) const { MemoryLocation Copy(*this); Copy.Size = NewSize; @@ -308,7 +332,8 @@ } bool operator==(const MemoryLocation &Other) const { - return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags; + return Ptr == Other.Ptr && PtrProvenance == Other.PtrProvenance && + Size == Other.Size && AATags == Other.AATags; } }; @@ -331,16 +356,19 @@ template <> struct DenseMapInfo { static inline MemoryLocation getEmptyKey() { return MemoryLocation(DenseMapInfo::getEmptyKey(), + DenseMapInfo::getEmptyKey(), DenseMapInfo::getEmptyKey()); } static inline MemoryLocation getTombstoneKey() { return MemoryLocation(DenseMapInfo::getTombstoneKey(), + DenseMapInfo::getTombstoneKey(), DenseMapInfo::getTombstoneKey()); } static unsigned getHashValue(const MemoryLocation &Val) { - return DenseMapInfo::getHashValue(Val.Ptr) ^ - DenseMapInfo::getHashValue(Val.Size) ^ - DenseMapInfo::getHashValue(Val.AATags); + return DenseMapInfo::getHashValue(static_cast( + llvm::hash_combine(Val.Ptr, Val.PtrProvenance, + DenseMapInfo::getHashValue(Val.Size), + DenseMapInfo::getHashValue(Val.AATags)))); } static bool isEqual(const MemoryLocation &LHS, const MemoryLocation &RHS) { return LHS == RHS; Index: llvm/include/llvm/Analysis/ScopedNoAliasAA.h =================================================================== --- llvm/include/llvm/Analysis/ScopedNoAliasAA.h +++ llvm/include/llvm/Analysis/ScopedNoAliasAA.h @@ -20,6 +20,7 @@ #include namespace llvm { +class DominatorTree; class Function; class MDNode; @@ -30,13 +31,13 @@ friend AAResultBase; public: + ScopedNoAliasAAResult(DominatorTree *DT) : AAResultBase(), DT(DT) {} + /// Handle invalidation events from the new pass manager. /// /// By definition, this result is stateless and so remains valid. - bool invalidate(Function &, const PreservedAnalyses &, - FunctionAnalysisManager::Invalidator &) { - return false; - } + bool invalidate(Function &F, const PreservedAnalyses &PA, + FunctionAnalysisManager::Invalidator &Inv); AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI); @@ -45,8 +46,24 @@ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2, AAQueryInfo &AAQI); + // FIXME: This interface can be removed once the legacy-pass-manager support + // is removed. + void setDT(DominatorTree *DT) { this->DT = DT; } + private: bool mayAliasInScopes(const MDNode *Scopes, const MDNode *NoAlias) const; + + bool findCompatibleNoAlias(const Value *P, const MDNode *ANoAlias, + const MDNode *BNoAlias, const DataLayout &DL, + SmallPtrSetImpl &Visited, + SmallVectorImpl &CompatibleSet, + int Depth = 0); + bool noAliasByIntrinsic(const MDNode *ANoAlias, const Value *APtr, + const MDNode *BNoAlias, const Value *BPtr, + const CallBase *CallA, const CallBase *CallB, + AAQueryInfo &AAQI); + + DominatorTree *DT; }; /// Analysis pass providing a never-invalidated alias analysis result. @@ -70,12 +87,18 @@ ScopedNoAliasAAWrapperPass(); - ScopedNoAliasAAResult &getResult() { return *Result; } + ScopedNoAliasAAResult &getResult() { + setDT(); + return *Result; + } const ScopedNoAliasAAResult &getResult() const { return *Result; } bool doInitialization(Module &M) override; bool doFinalization(Module &M) override; void getAnalysisUsage(AnalysisUsage &AU) const override; + +private: + void setDT(); }; //===--------------------------------------------------------------------===// Index: llvm/include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -606,6 +606,11 @@ case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::experimental_noalias_scope_decl: + case Intrinsic::noalias_decl: + case Intrinsic::noalias: + case Intrinsic::provenance_noalias: + case Intrinsic::noalias_arg_guard: + case Intrinsic::noalias_copy_guard: case Intrinsic::objectsize: case Intrinsic::ptr_annotation: case Intrinsic::var_annotation: Index: llvm/include/llvm/Analysis/ValueTracking.h =================================================================== --- llvm/include/llvm/Analysis/ValueTracking.h +++ llvm/include/llvm/Analysis/ValueTracking.h @@ -379,11 +379,15 @@ /// that the returned value has pointer type if the specified value does. If /// the MaxLookup value is non-zero, it limits the number of instructions to /// be stripped off. - const Value *getUnderlyingObject(const Value *V, unsigned MaxLookup = 6); - inline Value *getUnderlyingObject(Value *V, unsigned MaxLookup = 6) { + const Value * + getUnderlyingObject(const Value *V, unsigned MaxLookup = 6, + SmallVectorImpl *NoAlias = nullptr); + inline Value * + getUnderlyingObject(Value *V, unsigned MaxLookup = 6, + SmallVectorImpl *NoAlias = nullptr) { // Force const to avoid infinite recursion. const Value *VConst = V; - return const_cast(getUnderlyingObject(VConst, MaxLookup)); + return const_cast(getUnderlyingObject(VConst, MaxLookup, NoAlias)); } /// This method is similar to getUnderlyingObject except that it can @@ -413,10 +417,13 @@ /// /// Since A[i] and A[i-1] are independent pointers, getUnderlyingObjects /// should not assume that Curr and Prev share the same underlying object thus - /// it shouldn't look through the phi above. + /// it shouldn't look through the phi above. If a NoAlias vector is provided, + /// it is filled with any llvm.noalias intrinsics looked through to find the + /// underlying objects. void getUnderlyingObjects(const Value *V, SmallVectorImpl &Objects, - LoopInfo *LI = nullptr, unsigned MaxLookup = 6); + LoopInfo *LI = nullptr, unsigned MaxLookup = 6, + SmallVectorImpl *NoAlias = nullptr); /// This is a wrapper around getUnderlyingObjects and adds support for basic /// ptrtoint+arithmetic+inttoptr sequences. Index: llvm/include/llvm/Analysis/VectorUtils.h =================================================================== --- llvm/include/llvm/Analysis/VectorUtils.h +++ llvm/include/llvm/Analysis/VectorUtils.h @@ -459,8 +459,11 @@ /// metadata value that covers all of the individual values), and set I's /// metadata for M equal to the intersection value. /// +/// When RemoveNoAlias is true, MD_noalias will always get a null value. +/// /// This function always sets a (possibly null) value for each K in Kinds. -Instruction *propagateMetadata(Instruction *I, ArrayRef VL); +Instruction *propagateMetadata(Instruction *I, ArrayRef VL, + bool RemoveNoAlias = true); /// Create a mask that filters the members of an interleave group where there /// are gaps. Index: llvm/include/llvm/AsmParser/LLParser.h =================================================================== --- llvm/include/llvm/AsmParser/LLParser.h +++ llvm/include/llvm/AsmParser/LLParser.h @@ -47,6 +47,7 @@ t_LocalName, t_GlobalName, // Name in StrVal. t_APSInt, t_APFloat, // Value in APSIntVal/APFloatVal. t_Null, t_Undef, t_Zero, t_None, t_Poison, // No value. + t_UnknownProvenance, // No value. t_EmptyArray, // No value: [] t_Constant, // Value in ConstantVal. t_InlineAsm, // Value in FTy/StrVal/StrVal2/UIntVal. @@ -267,6 +268,9 @@ bool parseOrdering(AtomicOrdering &Ordering); bool parseOptionalStackAlignment(unsigned &Alignment); bool parseOptionalCommaAlign(MaybeAlign &Alignment, bool &AteExtraComma); + bool parseOptionalCommaNoaliasProvenance(Value *&V, LocTy &Loc, + PerFunctionState &PFS, + bool &AteExtraComma); bool parseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc, bool &AteExtraComma); bool parseAllocSizeArguments(unsigned &BaseSizeArg, Index: llvm/include/llvm/AsmParser/LLToken.h =================================================================== --- llvm/include/llvm/AsmParser/LLToken.h +++ llvm/include/llvm/AsmParser/LLToken.h @@ -91,6 +91,8 @@ kw_deplibs, // FIXME: Remove in 4.0 kw_datalayout, kw_volatile, + kw_ptr_provenance, + kw_unknown_provenance, kw_atomic, kw_unordered, kw_monotonic, Index: llvm/include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -384,6 +384,7 @@ CST_CODE_INLINEASM = 28, // INLINEASM: [sideeffect|alignstack| // asmdialect|unwind, // asmstr,conststr] + CST_CODE_UNKNOWN_PROVENANCE = 29, // UNKNOWN_PROVENANCE }; /// CastOpcodes - These are values used in the bitcode files to encode which Index: llvm/include/llvm/CodeGen/BasicTTIImpl.h =================================================================== --- llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -1684,6 +1684,12 @@ case Intrinsic::sideeffect: case Intrinsic::pseudoprobe: case Intrinsic::arithmetic_fence: + case Intrinsic::experimental_noalias_scope_decl: + case Intrinsic::noalias_decl: + case Intrinsic::noalias: + case Intrinsic::provenance_noalias: + case Intrinsic::noalias_arg_guard: + case Intrinsic::noalias_copy_guard: return 0; case Intrinsic::masked_store: { Type *Ty = Tys[0]; Index: llvm/include/llvm/CodeGen/MachineMemOperand.h =================================================================== --- llvm/include/llvm/CodeGen/MachineMemOperand.h +++ llvm/include/llvm/CodeGen/MachineMemOperand.h @@ -41,6 +41,12 @@ /// space. PointerUnion V; + /// The provenance of the pointer. When ConstantPointerNull, the provenance + /// can be any object. + /// FIXME: nullptr here means : use V as provenance. This will change in + /// future. + const Value *PtrProvenance = nullptr; + /// Offset - This is an offset from the base Value*. int64_t Offset; @@ -49,8 +55,9 @@ uint8_t StackID; explicit MachinePointerInfo(const Value *v, int64_t offset = 0, - uint8_t ID = 0) - : V(v), Offset(offset), StackID(ID) { + uint8_t ID = 0, + const Value *ptrProvenance = nullptr) + : V(v), PtrProvenance(ptrProvenance), Offset(offset), StackID(ID) { AddrSpace = v ? v->getType()->getPointerAddressSpace() : 0; } @@ -60,15 +67,16 @@ AddrSpace = v ? v->getAddressSpace() : 0; } - explicit MachinePointerInfo(unsigned AddressSpace = 0, int64_t offset = 0) - : V((const Value *)nullptr), Offset(offset), AddrSpace(AddressSpace), - StackID(0) {} + explicit MachinePointerInfo(unsigned AddressSpace = 0, int64_t offset = 0, + const Value *ptrProvenance = nullptr) + : V((const Value *)nullptr), PtrProvenance(ptrProvenance), Offset(offset), + AddrSpace(AddressSpace), StackID(0) {} explicit MachinePointerInfo( PointerUnion v, int64_t offset = 0, - uint8_t ID = 0) - : V(v), Offset(offset), StackID(ID) { + uint8_t ID = 0, const Value *ptrProvenance = nullptr) + : V(v), PtrProvenance(ptrProvenance), Offset(offset), StackID(ID) { if (V) { if (const auto *ValPtr = V.dyn_cast()) AddrSpace = ValPtr->getType()->getPointerAddressSpace(); @@ -216,6 +224,8 @@ const void *getOpaqueValue() const { return PtrInfo.V.getOpaqueValue(); } + const Value *getPtrProvenance() const { return PtrInfo.PtrProvenance; } + /// Return the raw flags of the source value, \see Flags. Flags getFlags() const { return FlagVals; } Index: llvm/include/llvm/IR/Constants.h =================================================================== --- llvm/include/llvm/IR/Constants.h +++ llvm/include/llvm/IR/Constants.h @@ -557,6 +557,35 @@ } }; +//===----------------------------------------------------------------------===// +/// A provenance pointer value indicating that the provenance can be anything. +/// +class UnknownProvenance final : public ConstantData { + friend class Constant; + + explicit UnknownProvenance(PointerType *T) + : ConstantData(T, Value::UnknownProvenanceVal) {} + + void destroyConstantImpl(); + +public: + UnknownProvenance(const UnknownProvenance &) = delete; + + /// Static factory methods - Return objects of the specified value + static UnknownProvenance *get(PointerType *T); + + /// Specialize the getType() method to always return an PointerType, + /// which reduces the amount of casting needed in parts of the compiler. + inline PointerType *getType() const { + return cast(Value::getType()); + } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const Value *V) { + return V->getValueID() == UnknownProvenanceVal; + } +}; + //===----------------------------------------------------------------------===// /// ConstantDataSequential - A vector or array constant whose element type is a /// simple 1/2/4/8-byte integer or half/bfloat/float/double, and whose elements Index: llvm/include/llvm/IR/IRBuilder.h =================================================================== --- llvm/include/llvm/IR/IRBuilder.h +++ llvm/include/llvm/IR/IRBuilder.h @@ -787,6 +787,66 @@ MetadataAsValue::get(Context, ScopeTag)); } + /// Create a llvm.noalias.decl intrinsic call. + Instruction *CreateNoAliasDeclaration(Value *AllocaPtr, Value *ObjId, + Value *Scope); + Instruction *CreateNoAliasDeclaration(Value *AllocaPtr, uint64_t ObjId, + Value *Scope) { + return CreateNoAliasDeclaration( + AllocaPtr, + ConstantInt::get(IntegerType::getInt64Ty(getContext()), ObjId), Scope); + } + Instruction *CreateNoAliasDeclaration(Value *AllocaPtr, MDNode *ScopeTag) { + uint64_t Zero = 0; + return CreateNoAliasDeclaration(AllocaPtr, Zero, + MetadataAsValue::get(Context, ScopeTag)); + } + + /// Create a llvm.noalias intrinsic call. + Instruction *CreateNoAliasPointer(Value *Ptr, Value *NoAliasDecl, + Value *AddrP, MDNode *ScopeTag, + const Twine &Name = "", + uint64_t ObjectId = 0) { + return CreateNoAliasPointer(Ptr, NoAliasDecl, AddrP, + MetadataAsValue::get(getContext(), ScopeTag), + Name, ObjectId); + } + Instruction *CreateNoAliasPointer(Value *Ptr, Value *NoAliasDecl, + Value *AddrP, Value *ScopeTag, + const Twine &Name = "", + uint64_t ObjectId = 0); + + /// Create a llvm.provenance.noalias intrinsic call. + Instruction *CreateProvenanceNoAliasPlain(Value *Ptr, Value *NoAliasDecl, + Value *AddrP, + Value *AddrP_Provenance, + Value *ObjId, MDNode *ScopeTag, + const Twine &Name = ""); + Instruction *CreateProvenanceNoAliasPlain(Value *Ptr, Value *NoAliasDecl, + Value *AddrP, + Value *AddrP_Provenance, + Value *ObjId, Value *ScopeValue, + const Twine &Name = ""); + + /// Create a llvm.noalias.arg.guard intrinsic call. + Instruction *CreateNoAliasArgGuard(Value *Ptr, Value *Provenance, + const Twine &Name = ""); + + /// Create llvm.noalias_copy_guard intrinsics. Returns the BasePtr when no + /// Offsets are provided. + Value *CreateNoAliasCopyGuard(Value *BasePtr, Value *NoAliasDel, + MDNode *Offsets, MDNode *ScopeTag, + const Twine &Name = ""); + +private: + /// Helper for creating noalias intrinsics + Instruction *CreateGenericNoAliasIntrinsic(Intrinsic::ID ID, Value *arg0, + ArrayRef args_opt, + ArrayRef MDNodes, + ArrayRef MDValues, + const Twine &Name = ""); + +public: /// Create a call to the experimental.gc.statepoint intrinsic to /// start a new statepoint sequence. CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Index: llvm/include/llvm/IR/InstVisitor.h =================================================================== --- llvm/include/llvm/IR/InstVisitor.h +++ llvm/include/llvm/IR/InstVisitor.h @@ -167,7 +167,7 @@ RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);} - RetTy visitLoadInst(LoadInst &I) { DELEGATE(UnaryInstruction);} + RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); } RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction);} RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction);} RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction);} Index: llvm/include/llvm/IR/Instruction.h =================================================================== --- llvm/include/llvm/IR/Instruction.h +++ llvm/include/llvm/IR/Instruction.h @@ -351,6 +351,7 @@ AAMDNodes getAAMetadata() const; /// Sets the AA metadata on this instruction from the AAMDNodes structure. + /// Sets the metadata on this instruction from the AAMDNodes structure. void setAAMetadata(const AAMDNodes &N); /// Retrieve the raw weight values of a conditional branch or select. @@ -524,6 +525,10 @@ /// currently inserted into a function. void dropLocation(); + /// Copy the ptr_provenance arg, or remove it. This only works on load and + /// store instructions + void copyPtrProvenanceOperand(const Instruction &Rhs); + private: // These are all implemented in Metadata.cpp. MDNode *getMetadataImpl(unsigned KindID) const; Index: llvm/include/llvm/IR/Instructions.h =================================================================== --- llvm/include/llvm/IR/Instructions.h +++ llvm/include/llvm/IR/Instructions.h @@ -172,7 +172,7 @@ /// An instruction for reading from memory. This uses the SubclassData field in /// Value to store whether or not the load is volatile. -class LoadInst : public UnaryInstruction { +class LoadInst : public Instruction { using VolatileField = BoolBitfieldElementT<0>; using AlignmentField = AlignmentBitfieldElementT; using OrderingField = AtomicOrderingBitfieldElementT; @@ -208,6 +208,15 @@ Align Align, AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd); + ~LoadInst() { + setLoadInstNumOperands(2); // needed by operator delete + } + // allocate space for exactly two operands + void *operator new(size_t s) { return User::operator new(s, 2); } + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + /// Return true if this is a load from a volatile memory location. bool isVolatile() const { return getSubclassData(); } @@ -274,6 +283,30 @@ return getPointerOperandType()->getPointerAddressSpace(); } + bool hasNoaliasProvenanceOperand() const { return getNumOperands() == 2; } + Value *getNoaliasProvenanceOperand() const { + assert(hasNoaliasProvenanceOperand() && "we need a ptr_provenance"); + return getOperand(1); + } + static unsigned getNoaliasProvenanceOperandIndex() { return 1U; } + void setNoaliasProvenanceOperand(Value *Provenance); + void removeNoaliasProvenanceOperand(); + Value *getPtrProvenance() const { + return hasNoaliasProvenanceOperand() ? + getNoaliasProvenanceOperand() : getOperand(getPointerOperandIndex()); + } + Optional getOptionalPtrProvenance() const { + if (hasNoaliasProvenanceOperand()) + return getNoaliasProvenanceOperand(); + else + return NoneType::None; + } + void copyOptionalPtrProvenance(const LoadInst *Rhs) { + if (Rhs->hasNoaliasProvenanceOperand()) + setNoaliasProvenanceOperand(Rhs->getNoaliasProvenanceOperand()); + else if (hasNoaliasProvenanceOperand()) + removeNoaliasProvenanceOperand(); + } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Load; @@ -296,6 +329,11 @@ SyncScope::ID SSID; }; +template <> +struct OperandTraits : public VariadicOperandTraits {}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LoadInst, Value) + //===----------------------------------------------------------------------===// // StoreInst Class //===----------------------------------------------------------------------===// @@ -332,8 +370,11 @@ StoreInst(Value *Val, Value *Ptr, bool isVolatile, Align Align, AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd); - // allocate space for exactly two operands - void *operator new(size_t S) { return User::operator new(S, 2); } + ~StoreInst() { + setStoreInstNumOperands(3); // needed by operator delete + } + // allocate space for exactly three operands + void *operator new(size_t S) { return User::operator new(S, 3); } void operator delete(void *Ptr) { User::operator delete(Ptr); } /// Return true if this is a store to a volatile memory location. @@ -408,6 +449,30 @@ return getPointerOperandType()->getPointerAddressSpace(); } + bool hasNoaliasProvenanceOperand() const { return getNumOperands() == 3; } + Value *getNoaliasProvenanceOperand() const { + assert(hasNoaliasProvenanceOperand() && "we need a ptr_provenance"); + return getOperand(2); + } + static unsigned getNoaliasProvenanceOperandIndex() { return 2U; } + void setNoaliasProvenanceOperand(Value *Provenance); + void removeNoaliasProvenanceOperand(); + Value *getPtrProvenance() const { + return hasNoaliasProvenanceOperand() ? + getNoaliasProvenanceOperand() : getOperand(getPointerOperandIndex()); + } + Optional getOptionalPtrProvenance() const { + if (hasNoaliasProvenanceOperand()) + return getNoaliasProvenanceOperand(); + else + return NoneType::None; + } + void copyOptionalPtrProvenance(const StoreInst *Rhs) { + if (Rhs->hasNoaliasProvenanceOperand()) + setNoaliasProvenanceOperand(Rhs->getNoaliasProvenanceOperand()); + else if (hasNoaliasProvenanceOperand()) + removeNoaliasProvenanceOperand(); + } // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Store; @@ -431,8 +496,7 @@ }; template <> -struct OperandTraits : public FixedNumOperandTraits { -}; +struct OperandTraits : public VariadicOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) Index: llvm/include/llvm/IR/IntrinsicInst.h =================================================================== --- llvm/include/llvm/IR/IntrinsicInst.h +++ llvm/include/llvm/IR/IntrinsicInst.h @@ -98,6 +98,11 @@ case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::experimental_noalias_scope_decl: + case Intrinsic::noalias_decl: + case Intrinsic::noalias: + case Intrinsic::provenance_noalias: + case Intrinsic::noalias_arg_guard: + case Intrinsic::noalias_copy_guard: case Intrinsic::objectsize: case Intrinsic::ptr_annotation: case Intrinsic::var_annotation: @@ -1326,6 +1331,20 @@ } }; +/// Returns true when two llvm.provenance.noalias represent the same noalias +/// info. +inline bool areProvenanceNoAliasCompatible(const IntrinsicInst *lhs, + const IntrinsicInst *rhs) { + assert(lhs->getIntrinsicID() == Intrinsic::provenance_noalias && + rhs->getIntrinsicID() == Intrinsic::provenance_noalias && + "Can only check noalias compatibility of provenance.noalias"); + return (lhs->getOperand(Intrinsic::ProvenanceNoAliasScopeArg) == + rhs->getOperand(Intrinsic::ProvenanceNoAliasScopeArg)) && + (lhs->getOperand(Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg) == + rhs->getOperand(Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg)) && + (lhs->getOperand(Intrinsic::ProvenanceNoAliasIdentifyPArg) == + rhs->getOperand(Intrinsic::ProvenanceNoAliasIdentifyPArg)); +} } // end namespace llvm #endif // LLVM_IR_INTRINSICINST_H Index: llvm/include/llvm/IR/Intrinsics.h =================================================================== --- llvm/include/llvm/IR/Intrinsics.h +++ llvm/include/llvm/IR/Intrinsics.h @@ -37,6 +37,27 @@ // Abstraction for the arguments of the noalias intrinsics static const int NoAliasScopeDeclScopeArg = 0; + // Abstraction for the arguments of the noalias intrinsics + static const int ProvenanceNoAliasNoAliasDeclArg = 1; + static const int ProvenanceNoAliasIdentifyPArg = 2; + static const int ProvenanceNoAliasIdentifyPProvenanceArg = 3; + static const int ProvenanceNoAliasIdentifyPObjIdArg = 4; + static const int ProvenanceNoAliasScopeArg = 5; + + static const int NoAliasNoAliasDeclArg = 1; + static const int NoAliasIdentifyPArg = 2; + static const int NoAliasIdentifyPObjIdArg = 3; + static const int NoAliasScopeArg = 4; + + static const int NoAliasDeclAllocaArg = 0; + static const int NoAliasDeclObjIdArg = 1; + static const int NoAliasDeclScopeArg = 2; + + static const int NoAliasCopyGuardIdentifyPBaseObject = 0; + static const int NoAliasCopyGuardNoAliasDeclArg = 1; + static const int NoAliasCopyGuardIndicesArg = 2; + static const int NoAliasCopyGuardScopeArg = 3; + // Intrinsic ID type. This is an opaque typedef to facilitate splitting up // the enum into target-specific enums. typedef unsigned ID; Index: llvm/include/llvm/IR/Intrinsics.td =================================================================== --- llvm/include/llvm/IR/Intrinsics.td +++ llvm/include/llvm/IR/Intrinsics.td @@ -573,6 +573,179 @@ : DefaultAttrsIntrinsic<[], [llvm_metadata_ty], [IntrInaccessibleMemOnly]>; // blocks LICM and some more +// The 'noalias intrinsics' allow to track dependencies so that the C99 restrict +// rules can be implemented. +// +// - llvm.noalias.decl +// - llvm.noalias +// - llvm.provenance.noalias +// - llvm.noalias.arg.guard +// - llvm.noalias.copy.guard +// +// +// Following arguments are typically used in the various intrinsics: +// - p: the value of the restrict pointer +// - p.addr: identifyP: the address of P: either a real object or a constant +// where the value is relative to 0: different 'identifyP' represent +// different restrict pointers, pointing to disjunct objects. +// - p.objId: when an alloca-object is split by SROA, multiple versions, +// representing the same variable declaration (=scope) can exist. +// This objId allows to differentiate between them. This is useful +// when later on, the alloca's are optimized away. +// - p.scope: metadata argument that refers to a list of alias.scope metadata +// entries that contains exactly one element. It represents the variable +// declaration that contains one or more restrict pointers. +// - p.decl: points to the @llvm.noalias.decl intrinsic associated with the +// declaration of a restrict variable. +// - p.alloca: points to the alloca associated with the declaration of a +// restrict variable +// - prov.p: the noalias pointer provenance associated with 'p'. +// - prov.p.addr: the noalias pointer provenance associated with 'p.addr'. +// - p.indices: metadata argument that refers to a list of metadata references. +// each reference points to a metadata array of indices. At the specified +// location, a restrict pointer is located. A '-1' indicates any index. +// (see llvm.noalias.copy.guard for an example) +// +// {p.addr, p.objId, p.scope} represent different ways of tracking the +// 'underlying P' object. A unique triplet represents a unique 'object P' +// +// NOTE: future enhancements might relax/enhance this notion for supporting +// an implementation of n4150 (alias sets). It is likely that an extra +// parameter should be introduced to differentiate p.addr from the p.universe. +// As far as C99 is concerned, p.addr == p.universe +// +// Also see: +// - LangRef.rst (Scoped NoAlias Related Intrinsics) +// - [llvm-dev] RFC: Full 'restrict' support in LLVM +// https://lists.llvm.org/pipermail/llvm-dev/2019-March/131127.html + +// 'llvm.noalias.decl' intrinsic: Inserted at the location of a restrict +// pointer declaration. Makes it possible to identify that a restrict scope is +// only valid inside the body of a loop. +// +// Purpose of the different arguments: +// - arg0: p.alloca: associates the restrict pointer declaration to an alloca. +// (can be 'null' if the alloca is optimized away). The alloca can be +// associated to multiple restrict pointers. +// - arg1: p.objId: identifies different objects, associated to the same +// variable declaration. Is needed to track splitting of alloca's in SROA. +// - arg2: p.scope: metadata representing the variable declaration. +// - returns: a dummy i8 pointer that is used to track dependencies, so that cse +// is not migrating llvm.provenance.noalias over declarations +def int_noalias_decl + : DefaultAttrsIntrinsic<[llvm_anyptr_ty], + [llvm_anyptr_ty, llvm_anyint_ty, llvm_metadata_ty], + [IntrInaccessibleMemOnly]>; // blocks LICM and some more + +// 'llvm.noalias' intrinsic: Introduces noalias information in the pointer +// computation path, normally right after the loading of the pointer value. +// It also blocks a number of optimizations. Once it is transformed into +// a llvm.provenance.noalias version, it can track noalias information and support +// complex optimizations. +// +// Purpose of the different arguments: +// - arg0: p: the incoming pointer value. +// - arg1: p.decl: dependency on llvm.noalias.decl (if available). The +// dependency makes it easier to handle the loop-unrolling case. +// - arg2: p.addr: identifyP: the address of P: either a real object or a +// constant where the value is relative to 0: different 'identifyP' +// represent different restrict pointers. +// - arg3: p.objId: identifies different objects, associated to the same +// variable declaration. Is needed to track splitting of alloca's in +// SROA. +// - arg4: p.scope: metadata representing the variable declaration. +// - returns: returns arg0 (although this is hidden for most optimization +// passes) +def int_noalias + : DefaultAttrsIntrinsic<[llvm_anyptr_ty], + [LLVMMatchType<0>, + llvm_anyptr_ty, llvm_anyptr_ty, // p.decl, p.addr + llvm_anyint_ty, llvm_metadata_ty], // p.objId, p.scope + [IntrArgMemOnly, IntrSpeculatable]>; + +// 'llvm.provenance.noalias' intrinsic: Introduces the noalias information on the +// provenance path. This intrinsic originates from a transformed +// 'llvm.noalias' intrinsic. +// +// Purpose of the different arguments: +// - arg0: p: the incoming ptr value. +// - arg1: p.decl: dependency on llvm.noalias.decl (if available). The +// dependency makes it easier to handle the loop-unrolling case. +// - arg2: p.addr: identifyP: the address of P: either a real object or a +// constant where the value is relative to 0: different 'identifyP' +// represent different restrict pointers. +// - arg3: prov.p.addr: the ptr_provenance associated with the identifyP: +// this is needed to handle cases like: 'int* restrict* restrict rprpi;' +// - arg4: p.objId: identifies different objects, associated to the same +// variable declaration. Is needed to track splitting of alloca's in +// SROA. +// - arg5: p.scope: metadata representing the variable declaration. +// - returns: returns arg0 (although this is hidden for most optimization +// passes) +// +// NOTES: +// - prov.p.addr (together with the other metadata set on the intrinsic), can be +// used to check if there are other reasons why this 'underlying P' object is +// different from another 'underlying P' (using tbaa, noalias annotations, ...) +// - p.decl, p.scope: it is possible that there initially is no +// llvm.noalias.decl dependency. For 'unknown-scope' scopes, it is possible +// that a later analysis connects the right scope and llvm.noalias.decl +// dependency. +// NOTE: Returned<0> must not be used here, or some optimizations (INDVARS) +// will be too optimistic as they see through the annotations, resulting in +// wrong code. +def int_provenance_noalias + : DefaultAttrsIntrinsic<[llvm_anyptr_ty], + [LLVMMatchType<0>, + llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyptr_ty, + llvm_anyint_ty, llvm_metadata_ty], + [IntrNoMem, IntrSpeculatable]>; + +// 'llvm.noalias.arg.guard' intrinsic: helps tracking the ptr_provenance. +// It guards pointers that escape through function arguments or are returned. +// After inlining, the noalias information can still be propagated +// +// Purpose of the different arguments: +// - arg0: p: the incoming ptr value. +// - arg1: prov.p: the ptr_provenance, associated with this pointer +// computation. +// - returns: arg0 (hidden for most optimization passes) +def int_noalias_arg_guard + : DefaultAttrsIntrinsic<[llvm_anyptr_ty], + [LLVMMatchType<0>, llvm_anyptr_ty], + [IntrNoMem, IntrSpeculatable]>; // NOTE: Returned<0> must not be used here + +// 'llvm.noalias.copy.guard' intrinsic: a guard that allows to track +// restrict pointers through a memcpy or a structured load/store. When such a +// memcpy or load/store pair is optimized away, the noalias dependency chain can +// be reconstructed. +// +// Purpose of the different arguments: +// %p.guard = +// llvm.noalias.copy.guard %p.alloca, %p.decl, !metadata !99, !metadata !98 +// - arg0: p.alloca: block of memory with potential restrict variables. +// - arg1: p.decl: associated llvm.noalias.decl instruction (if available) +// - arg2: p.indices: metadata list of list of indices, indicating where in the +// memory restrict pointers are located. +// - arg3: p.scope: metadata representing the variable declaration. +// - returns: arg0 (hidden for most optimization passes) +// +// Example of p.indices: +// struct FOO { +// int* restrict p1; +// int* p0; +// int* restrict p2; +// }; +// results in '!10' refering to: +// !10 = {!11, !12} +// !11 = { -1, 0 } +// !12 = { -1, 2 } +def int_noalias_copy_guard + : DefaultAttrsIntrinsic<[llvm_anyptr_ty], + [LLVMMatchType<0>, llvm_anyptr_ty, llvm_metadata_ty, + llvm_metadata_ty], + [IntrNoMem]>; + // Stack Protector Intrinsic - The stackprotector intrinsic writes the stack // guard to the correct place on the stack frame. def int_stackprotector : DefaultAttrsIntrinsic<[], [llvm_ptr_ty, llvm_ptrptr_ty], []>; Index: llvm/include/llvm/IR/MDBuilder.h =================================================================== --- llvm/include/llvm/IR/MDBuilder.h +++ llvm/include/llvm/IR/MDBuilder.h @@ -210,6 +210,48 @@ /// Return metadata containing an irreducible loop header weight. MDNode *createIrrLoopHeaderWeight(uint64_t Weight); + + struct NoAliasOffsetsField { + int64_t Offset = 0; + int64_t Size = 0; + const MDNode *Record = nullptr; + int64_t Count = 0; + + NoAliasOffsetsField(int64_t Offset, int64_t Size, int64_t Count) + : Offset(Offset), Size(Size), Count(Count) {} + NoAliasOffsetsField(int64_t Offset, const MDNode *Record, int64_t Count) + : Offset(Offset), Record(Record), Count(Count) {} + + bool isValid() const { return Record || Size; } + int64_t getFieldSize() const; + bool tryPullUp(); + bool tryMerge(const NoAliasOffsetsField &Rhs); + }; + + // NoAliasOffsets metadata looks like: + // { GlobalSize, [offset, (ptrsize | !struct), count]+ } + class NoAliasOffsetsNode { + const MDNode *Node; + + int64_t getOpAsInt64(unsigned Index) const; + + public: + explicit NoAliasOffsetsNode(const MDNode *N) : Node(N) { + assert(isValid(N) && "Invalid NoAliasOffsets format"); + } + + // Rough check for basic properties of a NoAliasOffsetsNode. + // Can also be used to differentiate the new style from the old indices. + static bool isValid(const MDNode *); + + std::size_t getNumEntries() const; + NoAliasOffsetsField getField(unsigned Index) const; + int64_t getGlobalSize() const; + }; + + /// Return metadata for a NoAliasOffsets description. + MDNode *createNoAliasOffsets(uint64_t Size, + ArrayRef Fields); }; } // end namespace llvm Index: llvm/include/llvm/IR/Metadata.h =================================================================== --- llvm/include/llvm/IR/Metadata.h +++ llvm/include/llvm/IR/Metadata.h @@ -646,6 +646,10 @@ } }; +/// Helper for merging ptr_provenance. FIXME: maybe needs to be at a different +/// location ? +Optional mergePtrProvenance(Optional Lhs, Optional Rhs); + /// A collection of metadata nodes that might be associated with a /// memory access used by the alias-analysis infrastructure. struct AAMDNodes { @@ -664,6 +668,11 @@ return TBAA || TBAAStruct || Scope || NoAlias; } + void clearNoAliasInfo() { + Scope = nullptr; + NoAlias = nullptr; + } + /// The tag for type-based alias analysis. MDNode *TBAA = nullptr; @@ -722,13 +731,13 @@ template<> struct DenseMapInfo { static inline AAMDNodes getEmptyKey() { - return AAMDNodes(DenseMapInfo::getEmptyKey(), - nullptr, nullptr, nullptr); + return AAMDNodes(DenseMapInfo::getEmptyKey(), nullptr, nullptr, + nullptr); } static inline AAMDNodes getTombstoneKey() { - return AAMDNodes(DenseMapInfo::getTombstoneKey(), - nullptr, nullptr, nullptr); + return AAMDNodes(DenseMapInfo::getTombstoneKey(), nullptr, + nullptr, nullptr); } static unsigned getHashValue(const AAMDNodes &Val) { @@ -1524,7 +1533,6 @@ // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_ISA_CONVERSION_FUNCTIONS(NamedMDNode, LLVMNamedMDNodeRef) - } // end namespace llvm #endif // LLVM_IR_METADATA_H Index: llvm/include/llvm/IR/User.h =================================================================== --- llvm/include/llvm/IR/User.h +++ llvm/include/llvm/IR/User.h @@ -209,6 +209,24 @@ NumUserOperands = NumOps; } + /// FIXME: As the number of operands is used to find the start of the + /// allocated memory in operator delete, we need to always think we have 3 + /// operands before delete. + void setStoreInstNumOperands(unsigned NumOps) { + assert((2 <= NumOps) && (NumOps <= 3) && + "StoreInst can only have 2 or 3 operands"); + NumUserOperands = NumOps; + } + + /// FIXME: As the number of operands is used to find the start of the + /// allocated memory in operator delete, we need to always think we have 2 + /// operands before delete. + void setLoadInstNumOperands(unsigned NumOps) { + assert((1 <= NumOps) && (NumOps <= 2) && + "LoadInst can only have 1 or 2 operands"); + NumUserOperands = NumOps; + } + /// Subclasses with hung off uses need to manage the operand count /// themselves. In these instances, the operand count isn't used to find the /// OperandList, so there's no issue in having the operand count change. Index: llvm/include/llvm/IR/Value.h =================================================================== --- llvm/include/llvm/IR/Value.h +++ llvm/include/llvm/IR/Value.h @@ -321,6 +321,13 @@ /// values. void replaceUsesOutsideBlock(Value *V, BasicBlock *BB); + /// replaceUsesInsideBlock - Go through the uses list for this definition and + /// make each use point to "V" instead of "this" when the use is inside the + /// block. + /// Unlike replaceAllUsesWith this function does not support basic block + /// values or constant users. + void replaceUsesInsideBlock(Value *V, BasicBlock *BB); + //---------------------------------------------------------------------- // Methods for handling the chain of uses of this Value. // @@ -670,6 +677,18 @@ ->stripPointerCastsForAliasAnalysis()); } + /// Strip off pointer casts, all-zero GEPs, aliases, invariant group + /// info and noalias intrinsics. + /// + /// Returns the original uncasted value. If this is called on a non-pointer + /// value, it returns 'this'. + const Value *stripPointerCastsAndInvariantGroupsAndNoAliasIntr() const; + Value *stripPointerCastsAndInvariantGroupsAndNoAliasIntr() { + return const_cast( + static_cast(this) + ->stripPointerCastsAndInvariantGroupsAndNoAliasIntr()); + } + /// Strip off pointer casts and all-constant inbounds GEPs. /// /// Returns the original pointer value. If this is called on a non-pointer Index: llvm/include/llvm/IR/Value.def =================================================================== --- llvm/include/llvm/IR/Value.def +++ llvm/include/llvm/IR/Value.def @@ -88,6 +88,7 @@ // ConstantData. HANDLE_CONSTANT(UndefValue) +HANDLE_CONSTANT(UnknownProvenance) HANDLE_CONSTANT(PoisonValue) HANDLE_CONSTANT(ConstantAggregateZero) HANDLE_CONSTANT(ConstantDataArray) Index: llvm/include/llvm/InitializePasses.h =================================================================== --- llvm/include/llvm/InitializePasses.h +++ llvm/include/llvm/InitializePasses.h @@ -115,6 +115,7 @@ void initializeCalledValuePropagationLegacyPassPass(PassRegistry &); void initializeCheckDebugMachineModulePass(PassRegistry &); void initializeCodeGenPreparePass(PassRegistry&); +void initializeConnectNoAliasDeclLegacyPassPass(PassRegistry &); void initializeConstantHoistingLegacyPassPass(PassRegistry&); void initializeConstantMergeLegacyPassPass(PassRegistry&); void initializeConstraintEliminationPass(PassRegistry &); @@ -368,6 +369,7 @@ void initializeProcessImplicitDefsPass(PassRegistry&); void initializeProfileSummaryInfoWrapperPassPass(PassRegistry&); void initializePromoteLegacyPassPass(PassRegistry&); +void initializePropagateAndConvertNoAliasLegacyPassPass(PassRegistry &); void initializePruneEHPass(PassRegistry&); void initializeRABasicPass(PassRegistry&); void initializePseudoProbeInserterPass(PassRegistry &); Index: llvm/include/llvm/LinkAllPasses.h =================================================================== --- llvm/include/llvm/LinkAllPasses.h +++ llvm/include/llvm/LinkAllPasses.h @@ -50,6 +50,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar/GVN.h" #include "llvm/Transforms/Scalar/InstSimplifyPass.h" +#include "llvm/Transforms/Scalar/PropagateAndConvertNoAlias.h" #include "llvm/Transforms/Scalar/Scalarizer.h" #include "llvm/Transforms/Utils.h" #include "llvm/Transforms/Utils/SymbolRewriter.h" @@ -222,6 +223,7 @@ (void) llvm::createSeparateConstOffsetFromGEPPass(); (void) llvm::createSpeculativeExecutionPass(); (void) llvm::createSpeculativeExecutionIfHasBranchDivergencePass(); + (void) llvm::createPropagateAndConvertNoAliasPass(); (void) llvm::createRewriteSymbolsPass(); (void) llvm::createStraightLineStrengthReducePass(); (void) llvm::createMemDerefPrinter(); Index: llvm/include/llvm/Transforms/Scalar.h =================================================================== --- llvm/include/llvm/Transforms/Scalar.h +++ llvm/include/llvm/Transforms/Scalar.h @@ -24,6 +24,12 @@ class ModulePass; class Pass; +//===----------------------------------------------------------------------===// +// +// ConnectNoAliasDecl - Connects llvm.noalias.XX intrinsics to llvm.noalias.decl +// +FunctionPass *createConnectNoAliasDeclPass(); + //===----------------------------------------------------------------------===// // // AlignmentFromAssumptions - Use assume intrinsics to set load/store @@ -457,6 +463,10 @@ // TargetTransformInfo::hasBranchDivergence() is true. FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass(); +// PropagateAndConvertNoAlias: move noalias intrinsics into a provenance of +// load/store instructions +FunctionPass *createPropagateAndConvertNoAliasPass(); + //===----------------------------------------------------------------------===// // // StraightLineStrengthReduce - This pass strength-reduces some certain Index: llvm/include/llvm/Transforms/Scalar/ConnectNoAliasDecl.h =================================================================== --- /dev/null +++ llvm/include/llvm/Transforms/Scalar/ConnectNoAliasDecl.h @@ -0,0 +1,32 @@ +//===- ConnectNoAliasDecl.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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This pass connects provenance.noalias intrinsics to the corresponding +/// llvm.noalias.decl, based on the alloca of the pointer. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_CONNECTNOALIASDECL_H +#define LLVM_TRANSFORMS_SCALAR_CONNECTNOALIASDECL_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { +class DominatorTree; + +class ConnectNoAliasDeclPass : public PassInfoMixin { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + + // Glue for old PM + bool runImpl(Function &F); +}; +} // namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_CONNECTNOALIASDECL_H Index: llvm/include/llvm/Transforms/Scalar/PropagateAndConvertNoAlias.h =================================================================== --- /dev/null +++ llvm/include/llvm/Transforms/Scalar/PropagateAndConvertNoAlias.h @@ -0,0 +1,37 @@ +//===- PropagateAndConvertNoAlias.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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This pass moves dependencies on llvm.noalias onto the ptr_provenance. +/// It also introduces and propagates provenance.noalias and noalias.arg.guard +/// intrinsics. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_PROPAGATEANDCONVERTNOALIAS_H +#define LLVM_TRANSFORMS_SCALAR_PROPAGATEANDCONVERTNOALIAS_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { +class DominatorTree; + +class PropagateAndConvertNoAliasPass + : public PassInfoMixin { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); + + // Glue for old PM + bool runImpl(Function &F, llvm::DominatorTree &DT); + +private: + bool doit(Function &F, llvm::DominatorTree &DT); +}; +} // namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_PROPAGATEANDCONVERTNOALIAS_H Index: llvm/include/llvm/Transforms/Utils/Cloning.h =================================================================== --- llvm/include/llvm/Transforms/Utils/Cloning.h +++ llvm/include/llvm/Transforms/Utils/Cloning.h @@ -345,6 +345,11 @@ void cloneAndAdaptNoAliasScopes(ArrayRef NoAliasDeclScopes, Instruction *IStart, Instruction *IEnd, LLVMContext &Context, StringRef Ext); +/// Connects noalias, provenance.noalias, noalias.copy.guard intrinsics to the +/// corresponding llvm.noalias.decl, based on the alloca of the underlying +/// p.addr. +/// \returns true when the function was modified. +bool propagateAndConnectNoAliasDecl(Function *F); } // end namespace llvm #endif // LLVM_TRANSFORMS_UTILS_CLONING_H Index: llvm/include/llvm/Transforms/Utils/NoAliasUtils.h =================================================================== --- /dev/null +++ llvm/include/llvm/Transforms/Utils/NoAliasUtils.h @@ -0,0 +1,39 @@ +//===- llvm/Transforms/Utils/NoAliasUtils.h - NoAlias utilities -*- 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 utilities for noalias metadata and intrinsics. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_NOALIASUTILS_H +#define LLVM_TRANSFORMS_UTILS_NOALIASUTILS_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" + +namespace llvm { +class Function; +class Loop; + +/// Connect llvm.noalias.decl to noalias/provenance.noalias intrinsics that are +/// associated with the unknown function scope and based on the same alloca. +/// At the same time, propagate the p.addr, p.objId and p.scope. +bool propagateAndConnectNoAliasDecl(Function *F); + +/// Clone the llvm.noalias.decl intrinsics that are defined inside the loop +/// and used outside the loop into the exit blocks. +void cloneNoAliasDeclIntoExit(Loop *L); +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_UTILS_NOALIASUTILS_H Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp =================================================================== --- llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -894,7 +894,13 @@ AAQueryInfo &AAQI) { assert(notDifferentParent(LocA.Ptr, LocB.Ptr) && "BasicAliasAnalysis doesn't support interprocedural queries."); - return aliasCheck(LocA.Ptr, LocA.Size, LocB.Ptr, LocB.Size, AAQI); + auto HasSeparatePtrProvenance = [](const auto &V) { + return V.PtrProvenance && V.PtrProvenance != V.Ptr; + }; + + return aliasCheck(LocA.Ptr, LocA.Size, LocB.Ptr, LocB.Size, AAQI, + !(HasSeparatePtrProvenance(LocA) || + HasSeparatePtrProvenance(LocB))); } /// Checks to see if the specified callsite can clobber the specified memory @@ -1528,15 +1534,22 @@ /// array references. AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size, const Value *V2, LocationSize V2Size, - AAQueryInfo &AAQI) { + AAQueryInfo &AAQI, bool StripNoAlias) { // If either of the memory references is empty, it doesn't matter what the // pointer values are. if (V1Size.isZero() || V2Size.isZero()) return AliasResult::NoAlias; + // FIXME: problem with MaxLookupSearch and aliasGEP.. is this still present? // Strip off any casts if they exist. - V1 = V1->stripPointerCastsForAliasAnalysis(); - V2 = V2->stripPointerCastsForAliasAnalysis(); + if (StripNoAlias) { + // No ptr_provenance - look through noalias intrinsics in a safe way + V1 = V1->stripPointerCastsAndInvariantGroupsAndNoAliasIntr(); + V2 = V2->stripPointerCastsAndInvariantGroupsAndNoAliasIntr(); + } else { + V1 = V1->stripPointerCastsForAliasAnalysis(); + V2 = V2->stripPointerCastsForAliasAnalysis(); + } // If V1 or V2 is undef, the result is NoAlias because we can always pick a // value for undef that aliases nothing in the program. Index: llvm/lib/Analysis/CaptureTracking.cpp =================================================================== --- llvm/lib/Analysis/CaptureTracking.cpp +++ llvm/lib/Analysis/CaptureTracking.cpp @@ -26,6 +26,7 @@ #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/Support/CommandLine.h" using namespace llvm; @@ -319,6 +320,15 @@ switch (I->getOpcode()) { case Instruction::Call: case Instruction::Invoke: { + if (auto *II = dyn_cast(I)) + if (II->getIntrinsicID() == Intrinsic::noalias || + II->getIntrinsicID() == Intrinsic::provenance_noalias || + II->getIntrinsicID() == Intrinsic::noalias_arg_guard || + II->getIntrinsicID() == Intrinsic::noalias_copy_guard) { + AddUses(I); + break; + } + auto *Call = cast(I); // Not captured if the callee is readonly, doesn't return a copy through // its return value and doesn't unwind (a readonly function can leak bits Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -39,6 +39,7 @@ #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Operator.h" #include "llvm/IR/PatternMatch.h" #include "llvm/IR/ValueHandle.h" @@ -5823,6 +5824,13 @@ break; } + case Intrinsic::noalias_arg_guard: { + // Only follow the plain path if undefined. Do not propagate null, that + // would incorrectly omit noalias information. + if (isa(Op0)) + return Op0; + break; + } default: break; } @@ -5830,8 +5838,30 @@ return nullptr; } -static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) { +static Value *simplifyProvenanceNoAlias(const Value *V) { + const IntrinsicInst *II = cast(V); + assert(II->getIntrinsicID() == Intrinsic::provenance_noalias); + + // Only follow the plain path if undefined. Do not propagate null, that + // would incorrectly omit noalias information. + Value *Op0 = II->getOperand(0); + if (isa(Op0)) { + return Op0; + } + // Check for compatibility: provenance.noalias(provenance.noalias) -> + // provenance.noalias + if (auto *DepII = dyn_cast(Op0)) { + if (DepII->getIntrinsicID() == Intrinsic::provenance_noalias) { + if (llvm::areProvenanceNoAliasCompatible(DepII, II)) { + return DepII; + } + } + } + return nullptr; +} + +static Value *simplifyIntrinsic(CallBase *Call, const SimplifyQuery &Q) { unsigned NumOperands = Call->arg_size(); Function *F = cast(Call->getCalledFunction()); Intrinsic::ID IID = F->getIntrinsicID(); @@ -6016,6 +6046,18 @@ FPI->getRoundingMode().getValue()); break; } + case Intrinsic::noalias: + case Intrinsic::noalias_copy_guard: { + // Only follow the plain path if undefined. Do not propagate null, that + // would incorrectly omit noalias information. + if (auto *Op0 = dyn_cast(Call->getArgOperand(0))) { + return Op0; + } + return nullptr; + } + case Intrinsic::provenance_noalias: { + return simplifyProvenanceNoAlias(Call); + } default: return nullptr; } Index: llvm/lib/Analysis/MemoryLocation.cpp =================================================================== --- llvm/lib/Analysis/MemoryLocation.cpp +++ llvm/lib/Analysis/MemoryLocation.cpp @@ -39,6 +39,7 @@ return MemoryLocation( LI->getPointerOperand(), + LI->getPtrProvenance(), LocationSize::precise(DL.getTypeStoreSize(LI->getType())), LI->getAAMetadata()); } @@ -47,6 +48,7 @@ const auto &DL = SI->getModule()->getDataLayout(); return MemoryLocation(SI->getPointerOperand(), + SI->getPtrProvenance(), LocationSize::precise(DL.getTypeStoreSize( SI->getValueOperand()->getType())), SI->getAAMetadata()); Index: llvm/lib/Analysis/ScopedNoAliasAA.cpp =================================================================== --- llvm/lib/Analysis/ScopedNoAliasAA.cpp +++ llvm/lib/Analysis/ScopedNoAliasAA.cpp @@ -34,23 +34,48 @@ #include "llvm/Analysis/ScopedNoAliasAA.h" #include "llvm/ADT/SetOperations.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/MemoryLocation.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/Dominators.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" using namespace llvm; +#define DEBUG_TYPE "scoped-noalias" + // A handy option for disabling scoped no-alias functionality. The same effect // can also be achieved by stripping the associated metadata tags from IR, but // this option is sometimes more convenient. -static cl::opt EnableScopedNoAlias("enable-scoped-noalias", - cl::init(true), cl::Hidden); +static cl::opt + EnableScopedNoAlias("enable-scoped-noalias", cl::init(true), cl::Hidden, + cl::desc("Enable use of scoped-noalias metadata")); + +static cl::opt + MaxNoAliasDepth("scoped-noalias-max-depth", cl::init(12), cl::Hidden, + cl::desc("Maximum depth for noalias intrinsic search")); + +static cl::opt MaxNoAliasPointerCaptureDepth( + "scoped-noalias-max-pointer-capture-check", cl::init(320), cl::Hidden, + cl::desc("Maximum depth for noalias pointer capture search")); + +// A 'Undef'as 'NoAliasProvenance' means 'no known extra information' about +// the pointer provenance. In that case, we need to follow the real pointer +// as it might contain extrainformation provided through llvm.noalias.arg.guard. +// A absent (nullptr) 'NoAliasProvenance', indicates that this access does not +// contain noalias provenance info. +static const Value *selectMemoryProvenance(const MemoryLocation &Loc) { + return Loc.PtrProvenance ? Loc.PtrProvenance : Loc.Ptr; +} AliasResult ScopedNoAliasAAResult::alias(const MemoryLocation &LocA, const MemoryLocation &LocB, @@ -69,6 +94,15 @@ if (!mayAliasInScopes(BScopes, ANoAlias)) return AliasResult::NoAlias; + LLVM_DEBUG(llvm::dbgs() << "ScopedNoAliasAAResult::alias\n"); + if (noAliasByIntrinsic(ANoAlias, selectMemoryProvenance(LocA), BNoAlias, + selectMemoryProvenance(LocB), nullptr, nullptr, AAQI)) + return AliasResult::NoAlias; + + if (noAliasByIntrinsic(BNoAlias, selectMemoryProvenance(LocB), ANoAlias, + selectMemoryProvenance(LocA), nullptr, nullptr, AAQI)) + return AliasResult::NoAlias; + // If they may alias, chain to the next AliasAnalysis. return AAResultBase::alias(LocA, LocB, AAQI); } @@ -79,12 +113,21 @@ if (!EnableScopedNoAlias) return AAResultBase::getModRefInfo(Call, Loc, AAQI); - if (!mayAliasInScopes(Loc.AATags.Scope, - Call->getMetadata(LLVMContext::MD_noalias))) + const MDNode *CSNoAlias = Call->getMetadata(LLVMContext::MD_noalias); + if (!mayAliasInScopes(Loc.AATags.Scope, CSNoAlias)) + return ModRefInfo::NoModRef; + + const MDNode *CSScopes = Call->getMetadata(LLVMContext::MD_alias_scope); + if (!mayAliasInScopes(CSScopes, Loc.AATags.NoAlias)) return ModRefInfo::NoModRef; - if (!mayAliasInScopes(Call->getMetadata(LLVMContext::MD_alias_scope), - Loc.AATags.NoAlias)) + LLVM_DEBUG(llvm::dbgs() << "ScopedNoAliasAAResult::getModRefInfo - 1\n"); + if (noAliasByIntrinsic(Loc.AATags.NoAlias, selectMemoryProvenance(Loc), + CSNoAlias, nullptr, nullptr, Call, AAQI)) + return ModRefInfo::NoModRef; + + if (noAliasByIntrinsic(CSNoAlias, nullptr, Loc.AATags.NoAlias, + selectMemoryProvenance(Loc), Call, nullptr, AAQI)) return ModRefInfo::NoModRef; return AAResultBase::getModRefInfo(Call, Loc, AAQI); @@ -96,12 +139,22 @@ if (!EnableScopedNoAlias) return AAResultBase::getModRefInfo(Call1, Call2, AAQI); - if (!mayAliasInScopes(Call1->getMetadata(LLVMContext::MD_alias_scope), - Call2->getMetadata(LLVMContext::MD_noalias))) + const MDNode *CS1Scopes = Call1->getMetadata(LLVMContext::MD_alias_scope); + const MDNode *CS2Scopes = Call2->getMetadata(LLVMContext::MD_alias_scope); + const MDNode *CS1NoAlias = Call1->getMetadata(LLVMContext::MD_noalias); + const MDNode *CS2NoAlias = Call2->getMetadata(LLVMContext::MD_noalias); + if (!mayAliasInScopes(CS1Scopes, Call2->getMetadata(LLVMContext::MD_noalias))) + return ModRefInfo::NoModRef; + + if (!mayAliasInScopes(CS2Scopes, Call1->getMetadata(LLVMContext::MD_noalias))) return ModRefInfo::NoModRef; - if (!mayAliasInScopes(Call2->getMetadata(LLVMContext::MD_alias_scope), - Call1->getMetadata(LLVMContext::MD_noalias))) + if (noAliasByIntrinsic(CS1NoAlias, nullptr, CS2NoAlias, nullptr, Call1, Call2, + AAQI)) + return ModRefInfo::NoModRef; + + if (noAliasByIntrinsic(CS2NoAlias, nullptr, CS1NoAlias, nullptr, Call2, Call1, + AAQI)) return ModRefInfo::NoModRef; return AAResultBase::getModRefInfo(Call1, Call2, AAQI); @@ -146,17 +199,503 @@ return true; } +bool ScopedNoAliasAAResult::findCompatibleNoAlias( + const Value *P, const MDNode *ANoAlias, const MDNode *BNoAlias, + const DataLayout &DL, SmallPtrSetImpl &Visited, + SmallVectorImpl &CompatibleSet, int Depth) { + // When a pointer is derived from multiple noalias calls, there are two + // potential reasons: + // 1. The path of derivation is uncertain (because of a select, PHI, etc.). + // 2. Some noalias calls are derived from other noalias calls. + // Logically, we need to treat (1) as an "and" and (2) as an "or" when + // checking for scope compatibility. If we don't know from which noalias call + // a pointer is derived, then we need to require compatibility with all of + // them. If we're derived from a noalias call that is derived from another + // noalias call, then we need the ability to effectively ignore the inner one + // in favor of the outer one (thus, we only need compatibility with one or + // the other). + // + // Scope compatibility means that, as with the noalias metadata, within each + // domain, the set of noalias intrinsic scopes is a subset of the noalias + // scopes. + // + // Given this, we check compatibility of the relevant sets of noalias calls + // from which LocA.Ptr might derive with both LocA.AATags.NoAlias and + // LocB.AATags.NoAlias, and LocB.Ptr does not derive from any of the noalias + // calls in some set, then we can conclude NoAlias. + // + // So if we have: + // noalias1 noalias3 + // | | + // noalias2 noalias4 + // | | + // \ / + // \ / + // \ / + // \ / + // select + // | + // noalias5 + // | + // noalias6 + // | + // PtrA + // + // - If PtrA is compatible with noalias6, and PtrB is also compatible, + // but does not derive from noalias6, then NoAlias. + // - If PtrA is compatible with noalias5, and PtrB is also compatible, + // but does not derive from noalias5, then NoAlias. + // - If PtrA is compatible with noalias2 and noalias4, and PtrB is also + // compatible, but does not derive from either, then NoAlias. + // - If PtrA is compatible with noalias2 and noalias3, and PtrB is also + // compatible, but does not derive from either, then NoAlias. + // - If PtrA is compatible with noalias1 and noalias4, and PtrB is also + // compatible, but does not derive from either, then NoAlias. + // - If PtrA is compatible with noalias1 and noalias3, and PtrB is also + // compatible, but does not derive from either, then NoAlias. + // + // We don't need, or want, to explicitly build N! sets to check for scope + // compatibility. Instead, recurse through the tree of underlying objects. + + SmallVector NoAliasCalls; + P = getUnderlyingObject(P, 0, &NoAliasCalls); + + // If we've already visited this underlying value (likely because this is a + // PHI that depends on itself, directly or indirectly), we must not have + // returned false the first time, so don't do so this time either. + if (!Visited.insert(P).second) + return true; + + auto getNoAliasScopeMDNode = [](IntrinsicInst *II) { + return dyn_cast( + cast( + II->getOperand(II->getIntrinsicID() == Intrinsic::provenance_noalias + ? Intrinsic::ProvenanceNoAliasScopeArg + : Intrinsic::NoAliasScopeArg)) + ->getMetadata()); + }; + + // Our pointer is derived from P, with NoAliasCalls along the way. + // Compatibility with any of them is fine. + auto NAI = find_if(NoAliasCalls, [&](Instruction *A) { + return !mayAliasInScopes(getNoAliasScopeMDNode(cast(A)), + ANoAlias) && + !mayAliasInScopes(getNoAliasScopeMDNode(cast(A)), + BNoAlias); + }); + if (NAI != NoAliasCalls.end()) { + CompatibleSet.push_back(*NAI); + return true; + } + + // We've not found a compatible noalias call, but we might be able to keep + // looking. If this underlying object is really a PHI or a select, we can + // check the incoming values. They all need to be compatible, and if so, we + // can take the union of all of the compatible noalias calls as the set to + // return for further validation. + SmallVector Children; + if (const auto *SI = dyn_cast(P)) { + Children.push_back(SI->getTrueValue()); + Children.push_back(SI->getFalseValue()); + } else if (const auto *PN = dyn_cast(P)) { + for (Value *IncommingValue : PN->incoming_values()) + Children.push_back(IncommingValue); + } + + if (Children.empty() || Depth == MaxNoAliasDepth) + return false; + + SmallPtrSet ChildVisited; + SmallVector ChildCompatSet; + for (auto &C : Children) { + ChildVisited.clear(); + ChildVisited.insert(Visited.begin(), Visited.end()); + ChildVisited.insert(P); + + ChildCompatSet.clear(); + if (!findCompatibleNoAlias(C, ANoAlias, BNoAlias, DL, ChildVisited, + ChildCompatSet, Depth + 1)) + return false; + + CompatibleSet.insert(CompatibleSet.end(), ChildCompatSet.begin(), + ChildCompatSet.end()); + } + + // All children were compatible, and we've added them to CompatibleSet. + return true; +} + +bool ScopedNoAliasAAResult::noAliasByIntrinsic( + const MDNode *ANoAlias, const Value *APtr, const MDNode *BNoAlias, + const Value *BPtr, const CallBase *CallA, const CallBase *CallB, + AAQueryInfo &AAQI) { + LLVM_DEBUG(llvm::dbgs() << ">ScopedNoAliasAAResult::noAliasByIntrinsic:{" + << (const void *)ANoAlias << "," << (const void *)APtr + << "},{" << (const void *)BNoAlias << "," + << (const void *)BPtr << "}\n"); + if (!ANoAlias || !BNoAlias) + return false; + + if (CallA) { + // We're querying a callsite against something else, where we want to know + // if the callsite (CallA) is derived from some noalias call(s) and the + // other thing is not derived from those noalias call(s). This can be + // determined only if CallA only accesses memory through its arguments. + FunctionModRefBehavior MRB = getModRefBehavior(CallA); + if (MRB != FMRB_OnlyAccessesArgumentPointees && + MRB != FMRB_OnlyReadsArgumentPointees) + return false; + + LLVM_DEBUG(dbgs() << "SNA: CSA: " << *CallA << "\n"); + // Since the memory-access behavior of CallA is determined only by its + // arguments, we can answer this query in the affirmative if we can prove a + // lack of aliasing for all pointer arguments. + for (Value *Arg : CallA->args()) { + if (!Arg->getType()->isPointerTy()) + continue; + + if (!noAliasByIntrinsic(ANoAlias, Arg, BNoAlias, BPtr, nullptr, CallB, + AAQI)) { + LLVM_DEBUG(dbgs() << "SNA: CSA: noalias fail for arg: " << *Arg + << "\n"); + return false; + } + } + + return true; + } + + const auto *AInst = dyn_cast(APtr); + // NOTE: this will also trigger for the UnknownProvenance. + if (!AInst || !AInst->getParent()) + return false; + const DataLayout &DL = AInst->getParent()->getModule()->getDataLayout(); + + if (!CallB && !BPtr) + return false; + + if (BPtr && isa(BPtr)) + return false; + + LLVM_DEBUG(dbgs() << "SNA: A: " << *APtr << "\n"); + LLVM_DEBUG(dbgs() << "SNB: "; if (CallB) dbgs() << "CSB: " << *CallB; + else if (BPtr) dbgs() << "B: " << *BPtr; + else dbgs() << "B: nullptr"; dbgs() << "\n"); + + SmallPtrSet Visited; + SmallVector CompatibleSet; + if (!findCompatibleNoAlias(APtr, ANoAlias, BNoAlias, DL, Visited, + CompatibleSet)) + return false; + + // Optimistically handling recusrive PHI's can result in an empty set. + if (CompatibleSet.empty()) + return false; + + LLVM_DEBUG(dbgs() << "SNA: Found a compatible set!\n"); +#ifndef NDEBUG + for (auto &C : CompatibleSet) + LLVM_DEBUG(dbgs() << "\t" << *C << "\n"); + LLVM_DEBUG(dbgs() << "\n"); +#endif + + // We have a set of compatible noalias calls (compatible with the scopes from + // both LocA and LocB) from which LocA.Ptr potentially derives. We now need + // to make sure that LocB.Ptr does not derive from any in that set. For + // correctness, there cannot be a depth limit here (if a pointer is derived + // from a noalias call, we must know). + SmallVector BObjs; + SmallVector BNoAliasCalls; + if (CallB) { + for (Value *Arg : CallB->args()) + getUnderlyingObjects(Arg, BObjs, nullptr, 0, &BNoAliasCalls); + } else { + getUnderlyingObjects(const_cast(BPtr), BObjs, nullptr, 0, + &BNoAliasCalls); + } + + LLVM_DEBUG(dbgs() << "SNA: B/CSB noalias:\n"); +#ifndef NDEBUG + for (auto &B : BNoAliasCalls) + LLVM_DEBUG(dbgs() << "\t" << *B << "\n"); + LLVM_DEBUG(dbgs() << "\n"); +#endif + + // We need to check now if any compatible llvm.provenance.noalias call is + // potentially using the same 'P' object as one of the 'BNoAliasCalls'. + // If this is true for at least one entry, we must bail out and assume + // 'may_alias' + + { + MDNode *NoAliasUnknownScopeMD = + AInst->getParent()->getParent()->getMetadata("noalias"); + + const struct { + unsigned IdentifyPObjIdArg; + unsigned ScopeArg; + unsigned IdentifyPArg; + } ProvNoAlias[2] = {{Intrinsic::NoAliasIdentifyPObjIdArg, + Intrinsic::NoAliasScopeArg, + Intrinsic::NoAliasIdentifyPArg}, + {Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg, + Intrinsic::ProvenanceNoAliasScopeArg, + Intrinsic::ProvenanceNoAliasIdentifyPArg}}; + for (Instruction *CA : CompatibleSet) { + LLVM_DEBUG(llvm::dbgs() << "- CA:" << *CA << "\n"); + assert(isa(CA) && + (cast(CA)->getIntrinsicID() == + llvm::Intrinsic::provenance_noalias || + cast(CA)->getIntrinsicID() == + llvm::Intrinsic::noalias)); + const int CA_IsProv = cast(CA)->getIntrinsicID() == + llvm::Intrinsic::provenance_noalias + ? 1 + : 0; + for (Instruction *CB : BNoAliasCalls) { + LLVM_DEBUG(llvm::dbgs() << "- CB:" << *CB << "\n"); + assert(isa(CB) && + (cast(CB)->getIntrinsicID() == + llvm::Intrinsic::provenance_noalias || + cast(CB)->getIntrinsicID() == + llvm::Intrinsic::noalias)); + const int CB_IsProv = cast(CB)->getIntrinsicID() == + llvm::Intrinsic::provenance_noalias + ? 1 + : 0; + + // With the llvm.provenance.noalias version, we have different parts + // that can represent a P: + // - the actual 'identifyP' address (or an offset vs an optimized away + // alloca) + // - the objectId (objectId's currently represent an offset to the + // original alloca of the object) + // - the scope (different scopes = different objects; with the exception + // of the 'unknown scope' an unknown scope can potentially be the same + // as a real variable scope. + // If any of these are different, the P will not alias => *P will also + // not alias + + // Let's start with the fast checks first; + + // Same call ? + if (CA == CB) { + LLVM_DEBUG(llvm::dbgs() << "SNA == SNB\n"); + return false; + } + + // - different objectId ? + { + // check ObjId first: if the obj id's (aka, offset in the object) are + // different, they represent different objects + auto ObjIdA = + cast( + CA->getOperand(ProvNoAlias[CA_IsProv].IdentifyPObjIdArg)) + ->getZExtValue(); + auto ObjIdB = + cast( + CB->getOperand(ProvNoAlias[CB_IsProv].IdentifyPObjIdArg)) + ->getZExtValue(); + if (ObjIdA != ObjIdB) { + LLVM_DEBUG(llvm::dbgs() << "SNA.ObjId != SNB.ObjId\n"); + continue; + } + } + + // Different Scope ? (except for unknown scope) + { + bool isDifferentPByScope = true; + auto *CASnaScope = CA->getOperand(ProvNoAlias[CA_IsProv].ScopeArg); + auto *CBSnaScope = CB->getOperand(ProvNoAlias[CB_IsProv].ScopeArg); + if (CASnaScope == CBSnaScope) { + // compatibility check below will resolve + isDifferentPByScope = false; + } else { + if (NoAliasUnknownScopeMD) { + if ((cast(CASnaScope)->getMetadata() == + NoAliasUnknownScopeMD) || + (cast(CBSnaScope)->getMetadata() == + NoAliasUnknownScopeMD)) { + isDifferentPByScope = false; + } + } + } + if (isDifferentPByScope) { + LLVM_DEBUG(llvm::dbgs() + << "SNA.Scope != SNB.Scope (and not 'unknown scope')\n"); + continue; + } + } + + // Different 'P' ? + { + Value *P_A = CA->getOperand(ProvNoAlias[CA_IsProv].IdentifyPArg); + Value *P_B = CB->getOperand(ProvNoAlias[CA_IsProv].IdentifyPArg); + + if (P_A == P_B) { + LLVM_DEBUG(dbgs() << " SNA.Scope == SNB.Scope, SNA.P == SNB.P\n"); + return false; + } + + if (auto *CP_A = dyn_cast(P_A)) { + if (auto *CP_B = dyn_cast(P_B)) { + CP_B = ConstantExpr::getBitCast(CP_B, CP_A->getType()); + Constant *Cmp = + ConstantExpr::getCompare(CmpInst::ICMP_NE, CP_A, CP_B, true); + if (Cmp && Cmp->isNullValue()) { + LLVM_DEBUG(dbgs() << " SNA.Scope == SNB.Scope, !(SNA.P != " + "SNB.P) as constant\n"); + return false; + } + } + } + // Check if P_A.addr and P_B.addr alias. If they don't, they describe + // different pointers. + LLVM_DEBUG(llvm::dbgs() + << " SNA.P=" << *P_A << ", SNB.P=" << *P_B << "\n"); + AAMDNodes P_A_Metadata = CA->getAAMetadata(); + AAMDNodes P_B_Metadata = CB->getAAMetadata(); + + // Check with 1 unit + MemoryLocation ML_P_A(P_A, 1ull, P_A_Metadata); + MemoryLocation ML_P_B(P_B, 1ull, P_B_Metadata); + + if (CA_IsProv) { + ML_P_A.PtrProvenance = CA->getOperand( + Intrinsic::ProvenanceNoAliasIdentifyPProvenanceArg); + } + if (CB_IsProv) { + ML_P_B.PtrProvenance = CB->getOperand( + Intrinsic::ProvenanceNoAliasIdentifyPProvenanceArg); + } + + if (getBestAAResults().alias(ML_P_A, ML_P_B, AAQI) != + AliasResult::NoAlias) { + LLVM_DEBUG(llvm::dbgs() << " P ... may alias\n"); + return false; + } + LLVM_DEBUG(llvm::dbgs() << " P is NoAlias\n"); + continue; + } + } + } + } + + // The noalias scope from the compatible intrinsics are really identified by + // their scope argument, and we need to make sure that LocB.Ptr is not only + // not derived from the calls currently in CompatibleSet, but also from any + // other intrinsic with the same scope. We can't just search the list of + // noalias intrinsics in BNoAliasCalls because we care not just about those + // direct dependence, but also dependence through capturing. Metadata + // do not have use lists, but MetadataAsValue objects do (and they are + // uniqued), so we can search their use list. As a result, however, + // correctness demands that the scope list has only one element (so that we + // can find all uses of that scope by noalias intrinsics by looking at the + // use list of the associated scope list). + SmallPtrSet CompatibleSetMembers(CompatibleSet.begin(), + CompatibleSet.end()); + SmallVector CompatibleSetMVs; + for (auto &C : CompatibleSet) { + CompatibleSetMVs.push_back(cast( + C->getOperand(cast(C)->getIntrinsicID() == + Intrinsic::provenance_noalias + ? Intrinsic::ProvenanceNoAliasScopeArg + : Intrinsic::NoAliasScopeArg))); + } + for (auto &MV : CompatibleSetMVs) + for (Use &U : MV->uses()) + if (auto *UI = dyn_cast(U.getUser())) { + // Skip noalias declarations + if (auto *CB = dyn_cast(UI)) + if (CB->getIntrinsicID() == Intrinsic::noalias_decl) + continue; + if (CompatibleSetMembers.insert(UI).second) { + CompatibleSet.push_back(UI); + LLVM_DEBUG(dbgs() << "SNA: Adding to compatible set based on MD use: " + << *UI << "\n"); + } + } + + LLVM_DEBUG(dbgs() << "SNA: B does not derive from the compatible set!\n"); + + // Note: This can be removed when legacy-pass-manager support is removed; + // BasicAA always has a DT available, and only under the hack where this is + // an immutable pass, not a function pass, might we not have one. + LLVM_DEBUG(dbgs() << "SNA: DT is " << (DT ? "available" : "unavailable") + << "\n"); + + // We now know that LocB.Ptr does not derive from any of the noalias calls in + // CompatibleSet directly. We do, however, need to make sure that it cannot + // derive from them by capture. + for (auto &V : BObjs) { + // If the underlying object is not an instruction, then it can't be + // capturing the output value of an instruction (specifically, the noalias + // intrinsic call), and we can ignore it. + auto *I = dyn_cast(V); + if (!I) + continue; + if (isIdentifiedFunctionLocal(I)) + continue; + + LLVM_DEBUG(dbgs() << "SNA: Capture check for B/CSB UO: " << *I << "\n"); + + // If the value from the noalias intrinsic has been captured prior to the + // instruction defining the underlying object, then LocB.Ptr might yet be + // derived from the return value of the noalias intrinsic, and we cannot + // conclude anything about the aliasing. + for (auto &C : CompatibleSet) + if (PointerMayBeCapturedBefore(C, /* ReturnCaptures */ false, + /* StoreCaptures */ false, I, DT, + /* IncludeI */ false, + MaxNoAliasPointerCaptureDepth)) { + LLVM_DEBUG(dbgs() << "SNA: Pointer " << *C << " might be captured!\n"); + return false; + } + } + + if (CallB) { + FunctionModRefBehavior MRB = getModRefBehavior(CallB); + if (MRB != FMRB_OnlyAccessesArgumentPointees && + MRB != FMRB_OnlyReadsArgumentPointees) { + // If we're querying against a callsite, and it might read from memory + // not based on its arguments, then we need to check whether or not the + // relevant noalias results have been captured prior to the callsite. + for (auto &C : CompatibleSet) + if (PointerMayBeCapturedBefore(C, /* ReturnCaptures */ false, + /* StoreCaptures */ false, CallB, DT)) { + LLVM_DEBUG(dbgs() + << "SNA: CSB: Pointer " << *C << " might be captured!\n"); + return false; + } + } + } + + LLVM_DEBUG(dbgs() << " SNA: noalias!\n"); + return true; +} + AnalysisKey ScopedNoAliasAA::Key; +bool ScopedNoAliasAAResult::invalidate( + Function &F, const PreservedAnalyses &PA, + FunctionAnalysisManager::Invalidator &Inv) { + if (Inv.invalidate(F, PA)) + return true; + + return false; +} + ScopedNoAliasAAResult ScopedNoAliasAA::run(Function &F, FunctionAnalysisManager &AM) { - return ScopedNoAliasAAResult(); + return ScopedNoAliasAAResult(&AM.getResult(F)); } char ScopedNoAliasAAWrapperPass::ID = 0; -INITIALIZE_PASS(ScopedNoAliasAAWrapperPass, "scoped-noalias-aa", - "Scoped NoAlias Alias Analysis", false, true) +INITIALIZE_PASS_BEGIN(ScopedNoAliasAAWrapperPass, "scoped-noalias-aa", + "Scoped NoAlias Alias Analysis", false, true) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_END(ScopedNoAliasAAWrapperPass, "scoped-noalias-aa", + "Scoped NoAlias Alias Analysis", false, true) ImmutablePass *llvm::createScopedNoAliasAAWrapperPass() { return new ScopedNoAliasAAWrapperPass(); @@ -167,7 +706,7 @@ } bool ScopedNoAliasAAWrapperPass::doInitialization(Module &M) { - Result.reset(new ScopedNoAliasAAResult()); + Result.reset(new ScopedNoAliasAAResult(nullptr)); return false; } @@ -176,6 +715,12 @@ return false; } +void ScopedNoAliasAAWrapperPass::setDT() { + if (auto *DTWP = getAnalysisIfAvailable()) + Result->setDT(&DTWP->getDomTree()); +} + void ScopedNoAliasAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); + AU.addUsedIfAvailable(); } Index: llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp =================================================================== --- llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -113,6 +113,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/InitializePasses.h" @@ -538,6 +539,21 @@ return Result; } +Optional +llvm::mergePtrProvenance(Optional Lhs, Optional Rhs) { + // Not sure about the best merge strategy yet. Normally, provenances with a + // common part should merge to the common part, except if that omits noalias + // info. + // For now: use a simpler algo. + if (Lhs == Rhs) + return Lhs; + + // Otherwise, return UnknownProvenance + return UnknownProvenance::get(cast(Lhs ? + Lhs.getValue()->getType() : + Rhs.getValue()->getType())); +} + static const MDNode *createAccessTag(const MDNode *AccessType) { // If there is no access type or the access type is the root node, then // we don't have any useful access tag to return. Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -4356,6 +4356,8 @@ const CallBase *Call, bool MustPreserveNullness) { switch (Call->getIntrinsicID()) { case Intrinsic::launder_invariant_group: + case Intrinsic::noalias_arg_guard: + case Intrinsic::noalias_copy_guard: case Intrinsic::strip_invariant_group: case Intrinsic::aarch64_irg: case Intrinsic::aarch64_tagp: @@ -4394,7 +4396,9 @@ return true; } -const Value *llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup) { +const Value * +llvm::getUnderlyingObject(const Value *V, unsigned MaxLookup, + SmallVectorImpl *NoAlias) { if (!V->getType()->isPointerTy()) return V; for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) { @@ -4417,6 +4421,30 @@ continue; } } else if (auto *Call = dyn_cast(V)) { + if (NoAlias) { + // We are gathering information for ScopedAANoAlias - + // Look through noalias and provenance.noalias intrinsic + if (Call->getIntrinsicID() == Intrinsic::provenance_noalias || + Call->getIntrinsicID() == Intrinsic::noalias) { + NoAlias->push_back(const_cast( + Call)); //@ FIXME: const cast should not be needed + V = Call->getArgOperand(0); + continue; + } + // Look trough noalias.arg.guard, and follow the ptr_provenance + if (Call->getIntrinsicID() == Intrinsic::noalias_arg_guard) { + V = Call->getArgOperand(1); + continue; + } + } else { + // We are not gathering information for SCopedAANoAlias - + // Look through noalias.arg.guard and follow the pointer path + if (Call->getIntrinsicID() == Intrinsic::noalias_arg_guard) { + V = Call->getArgOperand(0); + continue; + } + } + // CaptureTracking can know about special capturing properties of some // intrinsics like launder.invariant.group, that can't be expressed with // the attributes, but have properties like returning aliasing pointer. @@ -4441,13 +4469,14 @@ void llvm::getUnderlyingObjects(const Value *V, SmallVectorImpl &Objects, - LoopInfo *LI, unsigned MaxLookup) { + LoopInfo *LI, unsigned MaxLookup, + SmallVectorImpl *NoAlias) { SmallPtrSet Visited; SmallVector Worklist; Worklist.push_back(V); do { const Value *P = Worklist.pop_back_val(); - P = getUnderlyingObject(P, MaxLookup); + P = getUnderlyingObject(P, MaxLookup, NoAlias); if (!Visited.insert(P).second) continue; Index: llvm/lib/Analysis/VectorUtils.cpp =================================================================== --- llvm/lib/Analysis/VectorUtils.cpp +++ llvm/lib/Analysis/VectorUtils.cpp @@ -136,6 +136,7 @@ if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start || ID == Intrinsic::lifetime_end || ID == Intrinsic::assume || ID == Intrinsic::experimental_noalias_scope_decl || + ID == Intrinsic::noalias || ID == Intrinsic::provenance_noalias || ID == Intrinsic::sideeffect || ID == Intrinsic::pseudoprobe) return ID; return Intrinsic::not_intrinsic; @@ -723,7 +724,8 @@ } /// \returns \p I after propagating metadata from \p VL. -Instruction *llvm::propagateMetadata(Instruction *Inst, ArrayRef VL) { +Instruction *llvm::propagateMetadata(Instruction *Inst, ArrayRef VL, + bool RemoveNoAlias) { if (VL.empty()) return Inst; Instruction *I0 = cast(VL[0]); @@ -736,6 +738,8 @@ LLVMContext::MD_access_group}) { MDNode *MD = I0->getMetadata(Kind); + if (RemoveNoAlias && (Kind == LLVMContext::MD_noalias)) + MD = nullptr; for (int J = 1, E = VL.size(); MD && J != E; ++J) { const Instruction *IJ = cast(VL[J]); MDNode *IMD = IJ->getMetadata(Kind); @@ -761,7 +765,6 @@ llvm_unreachable("unhandled metadata"); } } - Inst->setMetadata(Kind, MD); } Index: llvm/lib/AsmParser/LLLexer.cpp =================================================================== --- llvm/lib/AsmParser/LLLexer.cpp +++ llvm/lib/AsmParser/LLLexer.cpp @@ -545,6 +545,7 @@ KEYWORD(unwind); KEYWORD(datalayout); KEYWORD(volatile); + KEYWORD(ptr_provenance); KEYWORD(atomic); KEYWORD(unordered); KEYWORD(monotonic); Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -1994,16 +1994,20 @@ /// end. bool LLParser::parseOptionalCommaAlign(MaybeAlign &Alignment, bool &AteExtraComma) { - AteExtraComma = false; - while (EatIfPresent(lltok::comma)) { + while (AteExtraComma || EatIfPresent(lltok::comma)) { + AteExtraComma = false; // Metadata at the end is an early exit. if (Lex.getKind() == lltok::MetadataVar) { AteExtraComma = true; return false; } - if (Lex.getKind() != lltok::kw_align) + // if we get here, ptr_provenance must not be possible any more + if (Lex.getKind() == lltok::kw_ptr_provenance) return error(Lex.getLoc(), "expected metadata or 'align'"); + if (Lex.getKind() != lltok::kw_align) + return error(Lex.getLoc(), + "expected metadata or 'align' or 'ptr_provenance'"); if (parseOptionalAlignment(Alignment)) return true; @@ -2012,6 +2016,27 @@ return false; } +/// parseOptionalCommandNoaliasProvenance +/// ::= +/// ::= ',' ptr_provenance int* %3 +/// +/// This returns with AteExtraComma set to true if it ate an excess comma at the +/// end. +bool LLParser::parseOptionalCommaNoaliasProvenance( + Value *&V, LLParser::LocTy &Loc, LLParser::PerFunctionState &PFS, + bool &AteExtraComma) { + assert(AteExtraComma == false); + if (EatIfPresent(lltok::comma)) { + if (Lex.getKind() == lltok::kw_ptr_provenance) { + Lex.Lex(); + return parseTypeAndValue(V, Loc, PFS); + } + + AteExtraComma = true; + } + return false; +} + /// parseOptionalCommaAddrSpace /// ::= /// ::= ',' addrspace(1) @@ -3031,6 +3056,7 @@ break; case lltok::kw_null: ID.Kind = ValID::t_Null; break; case lltok::kw_undef: ID.Kind = ValID::t_Undef; break; + case lltok::kw_unknown_provenance: ID.Kind = ValID::t_UnknownProvenance; break; case lltok::kw_poison: ID.Kind = ValID::t_Poison; break; case lltok::kw_zeroinitializer: ID.Kind = ValID::t_Zero; break; case lltok::kw_none: ID.Kind = ValID::t_None; break; @@ -5323,6 +5349,11 @@ return error(ID.Loc, "invalid type for undef constant"); V = UndefValue::get(Ty); return false; + case ValID::t_UnknownProvenance: + if (!Ty->isPointerTy()) + return error(ID.Loc, "unknown_provenance must be a pointer type"); + V = UnknownProvenance::get(cast(Ty)); + return false; case ValID::t_EmptyArray: if (!Ty->isArrayTy() || cast(Ty)->getNumElements() != 0) return error(ID.Loc, "invalid empty array initializer"); @@ -7137,6 +7168,8 @@ /// 'singlethread'? AtomicOrdering (',' 'align' i32)? int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) { Value *Val; LocTy Loc; + Value *NoaliasProvenance = nullptr; + LocTy NoaliasProvenanceLoc; MaybeAlign Alignment; bool AteExtraComma = false; bool isAtomic = false; @@ -7160,6 +7193,8 @@ parseToken(lltok::comma, "expected comma after load's type") || parseTypeAndValue(Val, Loc, PFS) || parseScopeAndOrdering(isAtomic, SSID, Ordering) || + parseOptionalCommaNoaliasProvenance( + NoaliasProvenance, NoaliasProvenanceLoc, PFS, AteExtraComma) || parseOptionalCommaAlign(Alignment, AteExtraComma)) return true; @@ -7183,7 +7218,10 @@ return error(ExplicitTypeLoc, "loading unsized types is not allowed"); if (!Alignment) Alignment = M->getDataLayout().getABITypeAlign(Ty); - Inst = new LoadInst(Ty, Val, "", isVolatile, *Alignment, Ordering, SSID); + auto *LI = new LoadInst(Ty, Val, "", isVolatile, *Alignment, Ordering, SSID); + if (NoaliasProvenance) + LI->setNoaliasProvenanceOperand(NoaliasProvenance); + Inst = LI; return AteExtraComma ? InstExtraComma : InstNormal; } @@ -7194,6 +7232,8 @@ /// 'singlethread'? AtomicOrdering (',' 'align' i32)? int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) { Value *Val, *Ptr; LocTy Loc, PtrLoc; + Value *NoaliasProvenance = nullptr; + LocTy NoaliasProvenanceLoc; MaybeAlign Alignment; bool AteExtraComma = false; bool isAtomic = false; @@ -7215,6 +7255,8 @@ parseToken(lltok::comma, "expected ',' after store operand") || parseTypeAndValue(Ptr, PtrLoc, PFS) || parseScopeAndOrdering(isAtomic, SSID, Ordering) || + parseOptionalCommaNoaliasProvenance( + NoaliasProvenance, NoaliasProvenanceLoc, PFS, AteExtraComma) || parseOptionalCommaAlign(Alignment, AteExtraComma)) return true; @@ -7236,7 +7278,11 @@ if (!Alignment) Alignment = M->getDataLayout().getABITypeAlign(Val->getType()); - Inst = new StoreInst(Val, Ptr, isVolatile, *Alignment, Ordering, SSID); + auto *SI = new StoreInst(Val, Ptr, isVolatile, *Alignment, Ordering, SSID); + if (NoaliasProvenance) + SI->setNoaliasProvenanceOperand(NoaliasProvenance); + Inst = SI; + return AteExtraComma ? InstExtraComma : InstNormal; } Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2447,6 +2447,11 @@ case bitc::CST_CODE_UNDEF: // UNDEF V = UndefValue::get(CurTy); break; + case bitc::CST_CODE_UNKNOWN_PROVENANCE: // UNKNOWN_PROVENANCE + if (!CurTy->isPointerTy()) + return error("Invalid type for a unknown_provenance"); + V = UnknownProvenance::get(cast(CurTy)); + break; case bitc::CST_CODE_POISON: // POISON V = PoisonValue::get(CurTy); break; @@ -4955,18 +4960,19 @@ InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol] + case bitc::FUNC_CODE_INST_LOAD: { + // LOAD: [opty, op, align, vol, [hasPtrProv, [PtrProv]]] unsigned OpNum = 0; Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || - (OpNum + 2 != Record.size() && OpNum + 3 != Record.size())) + (OpNum + 2 > Record.size())) return error("Invalid record"); if (!isa(Op->getType())) return error("Load operand is not a pointer type"); Type *Ty = nullptr; - if (OpNum + 3 == Record.size()) { + if (OpNum + 3 <= Record.size()) { Ty = getTypeByID(Record[OpNum++]); } else { Ty = cast(Op->getType())->getElementType(); @@ -4983,23 +4989,38 @@ return error("load of unsized type"); if (!Align) Align = TheModule->getDataLayout().getABITypeAlign(Ty); - I = new LoadInst(Ty, Op, "", Record[OpNum + 1], *Align); + bool IsVolatile = Record[OpNum + 1]; + OpNum += 2; + Value *PtrProvenance = nullptr; + if (OpNum < Record.size()) { + // Do we have a ptr_provenance ? + if (Record[OpNum++]) { + if (getValueTypePair(Record, OpNum, NextValueNo, PtrProvenance)) + return error("Invalid ptr_provenance operand"); + } + } + if (OpNum != Record.size()) + return error("Invalid record"); + I = new LoadInst(Ty, Op, "", IsVolatile, *Align); + if (PtrProvenance) + cast(I)->setNoaliasProvenanceOperand(PtrProvenance); InstructionList.push_back(I); break; } case bitc::FUNC_CODE_INST_LOADATOMIC: { - // LOADATOMIC: [opty, op, align, vol, ordering, ssid] + // LOADATOMIC: [opty, op, align, vol, ordering, ssid, + // [hasPtrProv,[PtrProv]]] unsigned OpNum = 0; Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || - (OpNum + 4 != Record.size() && OpNum + 5 != Record.size())) + (OpNum + 4 > Record.size())) return error("Invalid record"); if (!isa(Op->getType())) return error("Load operand is not a pointer type"); Type *Ty = nullptr; - if (OpNum + 5 == Record.size()) { + if (OpNum + 5 <= Record.size()) { Ty = getTypeByID(Record[OpNum++]); } else { Ty = cast(Op->getType())->getElementType(); @@ -5022,12 +5043,27 @@ return Err; if (!Align) return error("Alignment missing from atomic load"); - I = new LoadInst(Ty, Op, "", Record[OpNum + 1], *Align, Ordering, SSID); + bool IsVolatile = Record[OpNum + 1]; + OpNum += 4; + Value *PtrProvenance = nullptr; + if (OpNum < Record.size()) { + // Do we have a ptr_provenance ? + if (Record[OpNum++]) { + if (getValueTypePair(Record, OpNum, NextValueNo, PtrProvenance)) + return error("Invalid ptr_provenance operand"); + } + } + if (OpNum != Record.size()) + return error("Invalid record"); + I = new LoadInst(Ty, Op, "", IsVolatile, *Align, Ordering, SSID); + if (PtrProvenance) + cast(I)->setNoaliasProvenanceOperand(PtrProvenance); InstructionList.push_back(I); break; } case bitc::FUNC_CODE_INST_STORE: - case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol] + case bitc::FUNC_CODE_INST_STORE_OLD: { + // STORE2:[ptrty, ptr, val, align, vol, [hasPtrProv, [PtrProv]]] unsigned OpNum = 0; Value *Val, *Ptr; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || @@ -5036,7 +5072,7 @@ : popValue(Record, OpNum, NextValueNo, cast(Ptr->getType())->getElementType(), Val)) || - OpNum + 2 != Record.size()) + OpNum + 2 > Record.size()) return error("Invalid record"); if (Error Err = typeCheckLoadStoreInst(Val->getType(), Ptr->getType())) @@ -5049,13 +5085,28 @@ return error("store of unsized type"); if (!Align) Align = TheModule->getDataLayout().getABITypeAlign(Val->getType()); - I = new StoreInst(Val, Ptr, Record[OpNum + 1], *Align); + bool IsVolatile = Record[OpNum + 1]; + OpNum += 2; + Value *PtrProvenance = nullptr; + if (OpNum < Record.size()) { + // Do we have a ptr_provenance ? + if (Record[OpNum++]) { + if (getValueTypePair(Record, OpNum, NextValueNo, PtrProvenance)) + return error("Invalid ptr_provenance operand"); + } + } + if (OpNum != Record.size()) + return error("Invalid record"); + I = new StoreInst(Val, Ptr, IsVolatile, *Align); + if (PtrProvenance) + cast(I)->setNoaliasProvenanceOperand(PtrProvenance); InstructionList.push_back(I); break; } case bitc::FUNC_CODE_INST_STOREATOMIC: case bitc::FUNC_CODE_INST_STOREATOMIC_OLD: { - // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, ssid] + // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, ssid, + // [hasPtrProv, [PtrProv]]] unsigned OpNum = 0; Value *Val, *Ptr; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || @@ -5065,7 +5116,7 @@ : popValue(Record, OpNum, NextValueNo, cast(Ptr->getType())->getElementType(), Val)) || - OpNum + 4 != Record.size()) + OpNum + 4 > Record.size()) return error("Invalid record"); if (Error Err = typeCheckLoadStoreInst(Val->getType(), Ptr->getType())) @@ -5084,7 +5135,21 @@ return Err; if (!Align) return error("Alignment missing from atomic store"); - I = new StoreInst(Val, Ptr, Record[OpNum + 1], *Align, Ordering, SSID); + bool IsVolatile = Record[OpNum + 1]; + OpNum += 4; + Value *PtrProvenance = nullptr; + if (OpNum < Record.size()) { + // Do we have a ptr_provenance ? + if (Record[OpNum++]) { + if (getValueTypePair(Record, OpNum, NextValueNo, PtrProvenance)) + return error("Invalid ptr_provenance operand"); + } + } + if (OpNum != Record.size()) + return error("Invalid record"); + I = new StoreInst(Val, Ptr, IsVolatile, *Align, Ordering, SSID); + if (PtrProvenance) + cast(I)->setNoaliasProvenanceOperand(PtrProvenance); InstructionList.push_back(I); break; } Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2486,6 +2486,8 @@ Code = bitc::CST_CODE_POISON; } else if (isa(C)) { Code = bitc::CST_CODE_UNDEF; + } else if (isa(C)) { + Code = bitc::CST_CODE_UNKNOWN_PROVENANCE; } else if (const ConstantInt *IV = dyn_cast(C)) { if (IV->getBitWidth() <= 64) { uint64_t V = IV->getSExtValue(); @@ -3073,7 +3075,8 @@ pushValueAndType(I.getOperand(0), InstID, Vals); } else { Code = bitc::FUNC_CODE_INST_LOAD; - if (!pushValueAndType(I.getOperand(0), InstID, Vals)) // ptr + if (!pushValueAndType(I.getOperand(0), InstID, Vals) && + !cast(I).hasNoaliasProvenanceOperand()) // ptr AbbrevToUse = FUNCTION_INST_LOAD_ABBREV; } Vals.push_back(VE.getTypeID(I.getType())); @@ -3083,6 +3086,15 @@ Vals.push_back(getEncodedOrdering(cast(I).getOrdering())); Vals.push_back(getEncodedSyncScopeID(cast(I).getSyncScopeID())); } + if (cast(I).hasNoaliasProvenanceOperand()) { + Vals.push_back(true); // ptr_provenance present + pushValueAndType(cast(I).getNoaliasProvenanceOperand(), InstID, + Vals); // ptrty + ptr_provenance + } else { + // No ptr_provenance - do nothing for now, when in future more arguments + // are emitted, do not forget to emit a 'false': + // Vals.push_back(false); + } break; case Instruction::Store: if (cast(I).isAtomic()) @@ -3098,6 +3110,15 @@ Vals.push_back( getEncodedSyncScopeID(cast(I).getSyncScopeID())); } + if (cast(I).hasNoaliasProvenanceOperand()) { + Vals.push_back(true); // ptr_provenance present + pushValueAndType(cast(I).getNoaliasProvenanceOperand(), InstID, + Vals); // ptrty + ptr_provenance + } else { + // No ptr_provenance - do nothing for now, when in future more arguments + // are emitted, do not forget to emit a 'false': + // Vals.push_back(false); + } break; case Instruction::AtomicCmpXchg: Code = bitc::FUNC_CODE_INST_CMPXCHG; Index: llvm/lib/CodeGen/IntrinsicLowering.cpp =================================================================== --- llvm/lib/CodeGen/IntrinsicLowering.cpp +++ llvm/lib/CodeGen/IntrinsicLowering.cpp @@ -333,6 +333,15 @@ case Intrinsic::var_annotation: break; // Strip out these intrinsics + case Intrinsic::noalias_decl: + case Intrinsic::noalias: + case Intrinsic::provenance_noalias: + case Intrinsic::noalias_arg_guard: + case Intrinsic::noalias_copy_guard: + // Just forward the value + CI->replaceAllUsesWith(CI->getOperand(0)); + break; + case Intrinsic::memcpy: { Type *IntPtr = DL.getIntPtrType(Context); Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, Index: llvm/lib/CodeGen/MachineOperand.cpp =================================================================== --- llvm/lib/CodeGen/MachineOperand.cpp +++ llvm/lib/CodeGen/MachineOperand.cpp @@ -1185,6 +1185,10 @@ << "unknown-address"; } MachineOperand::printOperandOffset(OS, getOffset()); + if (getPtrProvenance()) { + OS << ", ptr_provenance "; + MIRFormatter::printIRValue(OS, *getPtrProvenance(), MST); + } if (getSize() > 0 && getAlign() != getSize()) OS << ", align " << getAlign().value(); if (getAlign() != getBaseAlign()) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6629,12 +6629,22 @@ case Intrinsic::annotation: case Intrinsic::ptr_annotation: + case Intrinsic::noalias: case Intrinsic::launder_invariant_group: case Intrinsic::strip_invariant_group: + case Intrinsic::provenance_noalias: + case Intrinsic::noalias_arg_guard: + case Intrinsic::noalias_copy_guard: // Drop the intrinsic, but forward the value setValue(&I, getValue(I.getOperand(0))); return; + case Intrinsic::noalias_decl: + // Generate a dummy value - it will never be used and should get optimized + // away + setValue(&I, DAG.getUNDEF(TLI.getPointerTy(DAG.getDataLayout()))); + return; + case Intrinsic::assume: case Intrinsic::experimental_noalias_scope_decl: case Intrinsic::var_annotation: Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -1580,6 +1580,11 @@ return; } + if (isa(CV)) { + Out << "unknown_provenance"; + return; + } + if (const ConstantExpr *CE = dyn_cast(CV)) { Out << CE->getOpcodeName(); WriteOptimizationInfo(Out, CE); @@ -4285,15 +4290,21 @@ } Out << ", "; TypePrinter.print(I.getType(), Out); - } else if (Operand) { // Print the normal way. + } else if (const auto *LI = dyn_cast(&I)) { + Out << ' '; + TypePrinter.print(LI->getType(), Out); + Out << ", "; + writeOperand(I.getOperand(0), true); + } else if (isa(&I)) { + Out << ' '; + writeOperand(I.getOperand(0), true); + Out << ", "; + writeOperand(I.getOperand(1), true); + } else if (Operand) { // Print the normal way. if (const auto *GEP = dyn_cast(&I)) { Out << ' '; TypePrinter.print(GEP->getSourceElementType(), Out); Out << ','; - } else if (const auto *LI = dyn_cast(&I)) { - Out << ' '; - TypePrinter.print(LI->getType(), Out); - Out << ','; } // PrintAllTypes - Instructions who have operands of all the same type @@ -4303,8 +4314,7 @@ Type *TheType = Operand->getType(); // Select, Store and ShuffleVector always print all types. - if (isa(I) || isa(I) || isa(I) - || isa(I)) { + if (isa(I) || isa(I) || isa(I)) { PrintAllTypes = true; } else { for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) { @@ -4334,11 +4344,19 @@ if (const LoadInst *LI = dyn_cast(&I)) { if (LI->isAtomic()) writeAtomic(LI->getContext(), LI->getOrdering(), LI->getSyncScopeID()); + if (LI->hasNoaliasProvenanceOperand()) { + Out << ", ptr_provenance "; + writeOperand(LI->getNoaliasProvenanceOperand(), true); + } if (LI->getAlignment()) Out << ", align " << LI->getAlignment(); } else if (const StoreInst *SI = dyn_cast(&I)) { if (SI->isAtomic()) writeAtomic(SI->getContext(), SI->getOrdering(), SI->getSyncScopeID()); + if (SI->hasNoaliasProvenanceOperand()) { + Out << ", ptr_provenance "; + writeOperand(SI->getNoaliasProvenanceOperand(), true); + } if (SI->getAlignment()) Out << ", align " << SI->getAlignment(); } else if (const AtomicCmpXchgInst *CXI = dyn_cast(&I)) { Index: llvm/lib/IR/Constants.cpp =================================================================== --- llvm/lib/IR/Constants.cpp +++ llvm/lib/IR/Constants.cpp @@ -1793,6 +1793,24 @@ getContext().pImpl->CPNConstants.erase(getType()); } +//---- UnknownProvenance::get() implementation. +// + +UnknownProvenance *UnknownProvenance::get(PointerType *Ty) { + std::unique_ptr &Entry = + Ty->getContext().pImpl->UPConstants[Ty]; + if (!Entry) + Entry.reset(new UnknownProvenance(Ty)); + + return Entry.get(); +} + +/// Remove the constant from the constant table. +void UnknownProvenance::destroyConstantImpl() { + getContext().pImpl->UPConstants.erase(getType()); +} + + UndefValue *UndefValue::get(Type *Ty) { std::unique_ptr &Entry = Ty->getContext().pImpl->UVConstants[Ty]; if (!Entry) Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -1096,6 +1096,14 @@ return wrap(ConstantPointerNull::get(unwrap(Ty))); } +LLVMBool LLVMIsUnknownProvenance(LLVMValueRef Val) { + return isa(unwrap(Val)); +} + +LLVMValueRef LLVMGetUnknownProvenance(LLVMTypeRef Ty) { + return wrap(UnknownProvenance::get(unwrap(Ty))); +} + /*--.. Operations on metadata nodes ........................................--*/ LLVMMetadataRef LLVMMDStringInContext2(LLVMContextRef C, const char *Str, Index: llvm/lib/IR/IRBuilder.cpp =================================================================== --- llvm/lib/IR/IRBuilder.cpp +++ llvm/lib/IR/IRBuilder.cpp @@ -503,6 +503,107 @@ return createCallHelper(FnIntrinsic, {Scope}, this); } +Instruction *IRBuilderBase::CreateNoAliasDeclaration(Value *AllocaPtr, + Value *ObjId, + Value *Scope) { + assert(AllocaPtr); + + SmallVector Types = {Type::getInt8PtrTy(getContext()), + AllocaPtr->getType(), ObjId->getType()}; + SmallVector Ops = {AllocaPtr, ObjId, Scope}; + + Module *M = BB->getModule(); + auto *FnIntrinsic = + Intrinsic::getDeclaration(M, Intrinsic::noalias_decl, Types); + return createCallHelper(FnIntrinsic, Ops, this); +} + +Instruction *IRBuilderBase::CreateNoAliasPointer(Value *Ptr, Value *NoAliasDecl, + Value *AddrP, Value *ScopeTag, + const Twine &Name, + uint64_t ObjectId) { + assert(Ptr && AddrP); + Value *I64_0 = + ConstantInt::get(IntegerType::getInt64Ty(getContext()), ObjectId); + return CreateGenericNoAliasIntrinsic(Intrinsic::noalias, Ptr, + {NoAliasDecl, AddrP, I64_0}, {}, + {ScopeTag}, Name); +} + +Instruction *IRBuilderBase::CreateProvenanceNoAliasPlain( + Value *Ptr, Value *NoAliasDecl, Value *AddrP, Value *AddrP_Provenance, + Value *ObjId, MDNode *ScopeTag, const Twine &Name) { + assert(Ptr && AddrP && AddrP_Provenance); + return CreateGenericNoAliasIntrinsic( + Intrinsic::provenance_noalias, Ptr, + {NoAliasDecl, AddrP, AddrP_Provenance, ObjId}, {ScopeTag}, {}, Name); +} + +Instruction *IRBuilderBase::CreateProvenanceNoAliasPlain( + Value *Ptr, Value *NoAliasDecl, Value *AddrP, Value *AddrP_Provenance, + Value *ObjId, Value *ScopeValue, const Twine &Name) { + assert(Ptr && AddrP && AddrP_Provenance); + return CreateGenericNoAliasIntrinsic( + Intrinsic::provenance_noalias, Ptr, + {NoAliasDecl, AddrP, AddrP_Provenance, ObjId}, {}, {ScopeValue}, Name); +} + +Instruction *IRBuilderBase::CreateNoAliasArgGuard(Value *Ptr, Value *Provenance, + const Twine &Name) { + return CreateGenericNoAliasIntrinsic(Intrinsic::noalias_arg_guard, Ptr, + {Provenance}, {}, {}, Name); +} + +Value *IRBuilderBase::CreateNoAliasCopyGuard(Value *BasePtr, Value *NoAliasDecl, + MDNode *Offsets, MDNode *ScopeTag, + const Twine &Name) { + if (!Offsets) + return BasePtr; + + assert(ScopeTag && "No scope metadata ?"); + return CreateGenericNoAliasIntrinsic(Intrinsic::noalias_copy_guard, BasePtr, + {NoAliasDecl}, {Offsets, ScopeTag}, {}, + Name); +} + +Instruction *IRBuilderBase::CreateGenericNoAliasIntrinsic( + Intrinsic::ID ID, Value *Ptr, ArrayRef args_opt, + ArrayRef MDNodes, ArrayRef MDValues, const Twine &Name) { + // FIXME: We can currently mangle just about everything, but not literal + // structs (for those, bitcast to i8*). + // FIXME: as far as I see in 'getMangledTypeStr', this should be ok now. + Value *CPtr = Ptr; + if (auto *STyp = + dyn_cast(CPtr->getType()->getPointerElementType())) { + if (STyp->isLiteral()) + CPtr = getCastedInt8PtrValue(CPtr); + } + + SmallVector Types = {CPtr->getType()}; + SmallVector Ops = {CPtr}; + for (auto *A : args_opt) { + Types.push_back(A->getType()); + Ops.push_back(A); + } + // For the metadata info, types must not be added: + for (auto *MD : MDNodes) { + Ops.push_back(MetadataAsValue::get(Context, MD)); + } + Ops.insert(Ops.end(), MDValues.begin(), MDValues.end()); + Module *M = BB->getModule(); + auto *FnIntrinsic = Intrinsic::getDeclaration(M, ID, Types); + Instruction *Ret = createCallHelper(FnIntrinsic, Ops, this, Name); + + if (Ret->getType() != Ptr->getType()) { + BitCastInst *BCI = new BitCastInst(Ret, Ptr->getType(), Name + ".cast"); + BB->getInstList().insert(InsertPt, BCI); + SetInstDebugLocation(BCI); + Ret = BCI; + } + + return Ret; +} + /// Create a call to a Masked Load intrinsic. /// \p Ty - vector type to load /// \p Ptr - base pointer for the load Index: llvm/lib/IR/Instruction.cpp =================================================================== --- llvm/lib/IR/Instruction.cpp +++ llvm/lib/IR/Instruction.cpp @@ -870,3 +870,27 @@ New->copyMetadata(*this); return New; } + +void Instruction::copyPtrProvenanceOperand(const Instruction &Rhs) { + //@ FIXME: maybe first check if we are load/store ? There should be room for + //@ optimization here. + llvm::Optional Provenance; + if (const LoadInst *LI = dyn_cast(&Rhs)) { + Provenance = LI->getOptionalPtrProvenance(); + } else if (const StoreInst *SI = dyn_cast(&Rhs)) { + Provenance = SI->getOptionalPtrProvenance(); + } + + if (LoadInst *LI=dyn_cast(this)) { + if (Provenance) + LI->setNoaliasProvenanceOperand(Provenance.getValue()); + else if (LI->hasNoaliasProvenanceOperand()) + LI->removeNoaliasProvenanceOperand(); + } else if (StoreInst *SI=dyn_cast(this)) { + if (Provenance) + SI->setNoaliasProvenanceOperand(Provenance.getValue()); + else if (SI->hasNoaliasProvenanceOperand()) + SI->removeNoaliasProvenanceOperand(); + } +} + Index: llvm/lib/IR/Instructions.cpp =================================================================== --- llvm/lib/IR/Instructions.cpp +++ llvm/lib/IR/Instructions.cpp @@ -1412,6 +1412,11 @@ "Ptr must have pointer type."); assert(!(isAtomic() && getAlignment() == 0) && "Alignment required for atomic load"); + assert((!hasNoaliasProvenanceOperand() || getOperand(1)) && + "ptr_provenance must be non-null"); + assert((!hasNoaliasProvenanceOperand() || + (getOperand(0)->getType() == getOperand(1)->getType())) && + "ptr_provenance must have the same type as the pointer"); } static Align computeLoadStoreDefaultAlign(Type *Ty, BasicBlock *BB) { @@ -1458,8 +1463,11 @@ LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, Align Align, AtomicOrdering Order, SyncScope::ID SSID, Instruction *InsertBef) - : UnaryInstruction(Ty, Load, Ptr, InsertBef) { + : Instruction(Ty, Load, OperandTraits::op_end(this) - 2, 2, + InsertBef) { assert(cast(Ptr->getType())->isOpaqueOrPointeeTypeMatches(Ty)); + setLoadInstNumOperands(1); + Op<0>() = Ptr; setVolatile(isVolatile); setAlignment(Align); setAtomic(Order, SSID); @@ -1470,7 +1478,10 @@ LoadInst::LoadInst(Type *Ty, Value *Ptr, const Twine &Name, bool isVolatile, Align Align, AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAE) - : UnaryInstruction(Ty, Load, Ptr, InsertAE) { + : Instruction(Ty, Load, OperandTraits::op_end(this) - 2, 2, + InsertAE) { + setLoadInstNumOperands(1); + Op<0>() = Ptr; assert(cast(Ptr->getType())->isOpaqueOrPointeeTypeMatches(Ty)); setVolatile(isVolatile); setAlignment(Align); @@ -1479,6 +1490,26 @@ setName(Name); } +void LoadInst::setNoaliasProvenanceOperand(llvm::LoadInst::Value *Provenance) { + assert(Provenance && "Needs a provenance"); + if (!hasNoaliasProvenanceOperand()) { + setLoadInstNumOperands(2); + // shift operands + setOperand(0, getOperand(1)); + } + setOperand(1, Provenance); + AssertOK(); +} + +void LoadInst::removeNoaliasProvenanceOperand() { + assert(hasNoaliasProvenanceOperand() && "nothing to remove"); + // shift operands + setOperand(1, getOperand(0)); + setOperand(0, nullptr); + setLoadInstNumOperands(1); + AssertOK(); +} + //===----------------------------------------------------------------------===// // StoreInst Implementation //===----------------------------------------------------------------------===// @@ -1492,6 +1523,11 @@ "Ptr must be a pointer to Val type!"); assert(!(isAtomic() && getAlignment() == 0) && "Alignment required for atomic store"); + assert((!hasNoaliasProvenanceOperand() || getOperand(2)) && + "ptr_provenance must be non-null"); + assert((!hasNoaliasProvenanceOperand() || + (getOperand(1)->getType() == getOperand(2)->getType())) && + "ptr_provenance must have the same type as the pointer"); } StoreInst::StoreInst(Value *val, Value *addr, Instruction *InsertBefore) @@ -1526,8 +1562,8 @@ AtomicOrdering Order, SyncScope::ID SSID, Instruction *InsertBefore) : Instruction(Type::getVoidTy(val->getContext()), Store, - OperandTraits::op_begin(this), - OperandTraits::operands(this), InsertBefore) { + OperandTraits::op_end(this) - 3, 3, InsertBefore) { + setStoreInstNumOperands(2); Op<0>() = val; Op<1>() = addr; setVolatile(isVolatile); @@ -1540,8 +1576,8 @@ AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd) : Instruction(Type::getVoidTy(val->getContext()), Store, - OperandTraits::op_begin(this), - OperandTraits::operands(this), InsertAtEnd) { + OperandTraits::op_end(this) - 3, 3, InsertAtEnd) { + setStoreInstNumOperands(2); Op<0>() = val; Op<1>() = addr; setVolatile(isVolatile); @@ -1550,6 +1586,29 @@ AssertOK(); } +void StoreInst::setNoaliasProvenanceOperand( + llvm::StoreInst::Value *Provenance) { + assert(Provenance && "Needs a provenance"); + if (!hasNoaliasProvenanceOperand()) { + setStoreInstNumOperands(3); + // shift uses; FIXME: can be made faster ? + setOperand(0, getOperand(1)); + setOperand(1, getOperand(2)); + } + setOperand(2, Provenance); + AssertOK(); +} + +void StoreInst::removeNoaliasProvenanceOperand() { + assert(hasNoaliasProvenanceOperand() && "nothing to remove"); + // make sure 'uses' are updated + setOperand(2, getOperand(1)); + setOperand(1, getOperand(0)); + setOperand(0, nullptr); + + setStoreInstNumOperands(2); + AssertOK(); +} //===----------------------------------------------------------------------===// // AtomicCmpXchgInst Implementation @@ -4603,13 +4662,32 @@ } LoadInst *LoadInst::cloneImpl() const { - return new LoadInst(getType(), getOperand(0), Twine(), isVolatile(), - getAlign(), getOrdering(), getSyncScopeID()); + LoadInst *Result = + new LoadInst(getType(), getOperand(0), Twine(), isVolatile(), getAlign(), + getOrdering(), getSyncScopeID()); + // - we must keep the same number of arguments (for vector optimizations) + // - if we duplicate the provenance, we can get into problems with passes + // that don't know how to handle it (Like MergeLoadStoreMotion shows) + // - safe alternative: keep the argument, but map it to unknown_provenance. + if (hasNoaliasProvenanceOperand()) + Result->setNoaliasProvenanceOperand(UnknownProvenance::get( + cast(getNoaliasProvenanceOperand()->getType()))); + return Result; } StoreInst *StoreInst::cloneImpl() const { - return new StoreInst(getOperand(0), getOperand(1), isVolatile(), getAlign(), - getOrdering(), getSyncScopeID()); + StoreInst *Result = + new StoreInst(getOperand(0), getOperand(1), isVolatile(), getAlign(), + getOrdering(), getSyncScopeID()); + + // we must keep the same number of arguments (for vector optimizations) + // - if we duplicate the provenance, we can get into problems with passes + // that don't know how to handle it (Like MergeLoadStoreMotion shows) + // - safe alternative: keep the argument, but map it to unknown_provenance. + if (hasNoaliasProvenanceOperand()) + Result->setNoaliasProvenanceOperand(UnknownProvenance::get( + cast(getNoaliasProvenanceOperand()->getType()))); + return Result; } AtomicCmpXchgInst *AtomicCmpXchgInst::cloneImpl() const { Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -1413,6 +1413,8 @@ DenseMap> CPNConstants; + DenseMap> UPConstants; + DenseMap> UVConstants; DenseMap> PVConstants; Index: llvm/lib/IR/LLVMContextImpl.cpp =================================================================== --- llvm/lib/IR/LLVMContextImpl.cpp +++ llvm/lib/IR/LLVMContextImpl.cpp @@ -98,6 +98,7 @@ CAZConstants.clear(); CPNConstants.clear(); + UPConstants.clear(); UVConstants.clear(); PVConstants.clear(); IntConstants.clear(); Index: llvm/lib/IR/MDBuilder.cpp =================================================================== --- llvm/lib/IR/MDBuilder.cpp +++ llvm/lib/IR/MDBuilder.cpp @@ -306,6 +306,28 @@ return MDNode::get(Context, Vals); } +MDNode *MDBuilder::createNoAliasOffsets( + uint64_t Size, ArrayRef Fields) { + if (Fields.empty()) + return nullptr; + + SmallVector Vals(Fields.size() * 3 + 1); + Type *Int64 = Type::getInt64Ty(Context); + unsigned I = 0; + + Vals[I++] = createConstant(ConstantInt::get(Int64, Size)); + for (const auto &F : Fields) { + Vals[I++] = createConstant(ConstantInt::get(Int64, F.Offset)); + if (F.Record) + Vals[I++] = const_cast(F.Record); + else + Vals[I++] = createConstant(ConstantInt::get(Int64, F.Size)); + Vals[I++] = createConstant(ConstantInt::get(Int64, F.Count)); + } + + return MDNode::get(Context, Vals); +} + MDNode *MDBuilder::createPseudoProbeDesc(uint64_t GUID, uint64_t Hash, Function *F) { auto *Int64Ty = Type::getInt64Ty(Context); @@ -315,3 +337,100 @@ Ops[2] = createString(F->getName()); return MDNode::get(Context, Ops); } + +static int64_t getMAsInt64(Metadata *M) { + return cast(cast(M)->getValue()) + ->getZExtValue(); +} + +int64_t MDBuilder::NoAliasOffsetsField::getFieldSize() const { + if (Record) + return getMAsInt64(Record->getOperand(0)); + else + return Size; +} + +bool MDBuilder::NoAliasOffsetsField::tryPullUp() { + if (!Record || Record->getNumOperands() != 4) + return false; + + NoAliasOffsetsNode Next(Record); + NoAliasOffsetsField SingleField = Next.getField(0); + + // We can only pull in the values if the refering NoAliasOffsets contain a + // single field that spans the full size. + if (SingleField.Offset != 0) + return false; + + if (SingleField.getFieldSize() * SingleField.Count != Next.getGlobalSize()) + return false; + + // Pull up ! + // Offset stays the same + Size = SingleField.Size; + Record = SingleField.Record; + Count = Count * SingleField.Count; + + return true; +} + +bool MDBuilder::NoAliasOffsetsField::tryMerge( + const MDBuilder::NoAliasOffsetsField &Rhs) { + if (Size != Rhs.Size || Record != Rhs.Record) + return false; + + // Do not merge an unbounded field + if (Count == 0 || Rhs.Count == 0) + return false; + + // Check adjacent + if (Offset + Count * getFieldSize() == Rhs.Offset) { + // Sizes are equal, offsets aligned + Count += Rhs.Count; + return true; + } + + // Check if the entries cover the same thing (Unions) + if (Offset == Rhs.Offset) { + Count = std::max(Count, Rhs.Count); + return true; + } + + return false; +} + +int64_t MDBuilder::NoAliasOffsetsNode::getOpAsInt64(unsigned Index) const { + return getMAsInt64(Node->getOperand(Index)); +} + +bool MDBuilder::NoAliasOffsetsNode::isValid(const MDNode *N) { + if (!N) + return false; + if (N->getNumOperands() % 3 != 1) + return false; + if (N->getNumOperands() < 4) + return false; + if (!isa(N->getOperand(0))) + return false; + + return true; +} + +std::size_t MDBuilder::NoAliasOffsetsNode::getNumEntries() const { + return (Node->getNumOperands() - 1) / 3; +} + +MDBuilder::NoAliasOffsetsField +MDBuilder::NoAliasOffsetsNode::getField(unsigned Index) const { + unsigned BaseIndex = 1 + Index * 3; + int64_t Offset = getOpAsInt64(BaseIndex + 0); + int64_t Count = getOpAsInt64(BaseIndex + 2); + if (auto *Record = dyn_cast(Node->getOperand(BaseIndex + 1))) + return NoAliasOffsetsField(Offset, Record, Count); + else + return NoAliasOffsetsField(Offset, getOpAsInt64(BaseIndex + 1), Count); +} + +int64_t MDBuilder::NoAliasOffsetsNode::getGlobalSize() const { + return getOpAsInt64(0); +} Index: llvm/lib/IR/Metadata.cpp =================================================================== --- llvm/lib/IR/Metadata.cpp +++ llvm/lib/IR/Metadata.cpp @@ -38,6 +38,7 @@ #include "llvm/IR/GlobalObject.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" Index: llvm/lib/IR/Value.cpp =================================================================== --- llvm/lib/IR/Value.cpp +++ llvm/lib/IR/Value.cpp @@ -597,6 +597,23 @@ }); } +// Like replaceAllUsesWith except it does not handle constants or basic blocks. +// This routine leaves uses outside BB. +void Value::replaceUsesInsideBlock(Value *New, BasicBlock *BB) { + assert(New && "Value::replaceUsesInsideBlock(, BB) is invalid!"); + assert(!contains(New, this) && + "this->replaceUsesInsideBlock(expr(this), BB) is NOT valid!"); + assert(New->getType() == getType() && + "replaceUses of value with new value of different type!"); + assert(BB && "Basic block that may contain a use of 'New' must be defined\n"); + + replaceUsesWithIf(New, [BB](Use &U) { + auto *I = dyn_cast(U.getUser()); + // Don't replace if it's an instruction in the BB basic block. + return !I || I->getParent() == BB; + }); +} + namespace { // Various metrics for how much to strip off of pointers. enum PointerStripKind { @@ -604,6 +621,7 @@ PSK_ZeroIndicesAndAliases, PSK_ZeroIndicesSameRepresentation, PSK_ForAliasAnalysis, + PSK_ZeroIndicesAndInvariantGroupsAndNoAliasIntr, PSK_InBoundsConstantIndices, PSK_InBounds }; @@ -630,6 +648,7 @@ case PSK_ZeroIndicesAndAliases: case PSK_ZeroIndicesSameRepresentation: case PSK_ForAliasAnalysis: + case PSK_ZeroIndicesAndInvariantGroupsAndNoAliasIntr: if (!GEP->hasAllZeroIndices()) return V; break; @@ -654,7 +673,9 @@ V = cast(V)->getOperand(0); } else if (StripKind == PSK_ZeroIndicesAndAliases && isa(V)) { V = cast(V)->getAliasee(); - } else if (StripKind == PSK_ForAliasAnalysis && isa(V) && + } else if ((StripKind == PSK_ForAliasAnalysis || + StripKind == PSK_ZeroIndicesAndInvariantGroupsAndNoAliasIntr) && + isa(V) && cast(V)->getNumIncomingValues() == 1) { V = cast(V)->getIncomingValue(0); } else { @@ -672,6 +693,17 @@ V = Call->getArgOperand(0); continue; } + // Same as above, but also for noalias intrinsics + if (StripKind == PSK_ZeroIndicesAndInvariantGroupsAndNoAliasIntr && + (Call->getIntrinsicID() == Intrinsic::launder_invariant_group || + Call->getIntrinsicID() == Intrinsic::strip_invariant_group || + Call->getIntrinsicID() == Intrinsic::noalias || + Call->getIntrinsicID() == Intrinsic::provenance_noalias || + Call->getIntrinsicID() == Intrinsic::noalias_arg_guard || + Call->getIntrinsicID() == Intrinsic::noalias_copy_guard)) { + V = Call->getArgOperand(0); + continue; + } } return V; } @@ -702,6 +734,11 @@ return stripPointerCastsAndOffsets(this); } +const Value *Value::stripPointerCastsAndInvariantGroupsAndNoAliasIntr() const { + return stripPointerCastsAndOffsets< + PSK_ZeroIndicesAndInvariantGroupsAndNoAliasIntr>(this); +} + const Value *Value::stripAndAccumulateConstantOffsets( const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup, Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -5395,6 +5395,87 @@ &Call); break; } + case Intrinsic::noalias_decl: { + Assert( + (isa( + Call.getArgOperand(Intrinsic::NoAliasDeclAllocaArg)) || + isa(Call.getArgOperand(Intrinsic::NoAliasDeclAllocaArg))), + "llvm.noalias.decl must refer to a null-ptr or an alloca instruction", + Call); + break; + } + case Intrinsic::noalias: { + auto *DA = Call.getArgOperand(Intrinsic::NoAliasNoAliasDeclArg); + if (!isa(DA) && !isa(DA)) { + auto *DeclSite = dyn_cast(DA); + Assert(DeclSite, "llvm.noalias arg1 must refer to a llvm.noalias.decl", + Call); + Assert((DeclSite->getArgOperand(Intrinsic::NoAliasDeclObjIdArg) == + Call.getArgOperand(Intrinsic::NoAliasIdentifyPObjIdArg)), + "llvm.noalias objId arg must match with llvm.noalias.decl", Call); + Assert((DeclSite->getArgOperand(Intrinsic::NoAliasDeclScopeArg) == + Call.getArgOperand(Intrinsic::NoAliasScopeArg)), + "llvm.noalias scope arg must match with llvm.noalias.decl", Call); + } + break; + } + case Intrinsic::provenance_noalias: { + auto *DA = Call.getArgOperand(Intrinsic::ProvenanceNoAliasNoAliasDeclArg); + if (!isa(DA) && !isa(DA)) { + // JumpThreading can duplicate llvm.noalias.decl. + // I do not think we should prohibit that. + SmallVector NoAliasDeclarations; + { + DenseSet Handled; + SmallVector Worklist = {DA}; + while (!Worklist.empty()) { + auto *V = Worklist.pop_back_val(); + if (Handled.insert(V).second) { + if (isa(V)) { + NoAliasDeclarations.push_back(cast(V)); + } else if (PHINode *PHI = dyn_cast(V)) { + auto OV = PHI->operand_values(); + Worklist.insert(Worklist.end(), OV.begin(), OV.end()); + } else if (isa(V)) { + // ignore undefs + } else if (isa(V)) { + // ignore nullptr + } else { + Assert( + false, + "llvm.provenance.noalias depends on something that is not a " + "llvm.noalias.decl", + Call); + } + } + } + } + + Assert(!NoAliasDeclarations.empty(), + "llvm.provenance.noalias should depend on a llvm.noalias.decl", + Call); + for (auto *CB : NoAliasDeclarations) { + Assert(CB, + "llvm.provenance.noalias arg1 must refer to a llvm.noalias.decl", + Call); + Assert(CB->getIntrinsicID() == Intrinsic::noalias_decl, + "llvm.provenance.noalias arg1 must refer to a llvm.noalias.decl", + Call); + Assert( + (CB->getArgOperand(Intrinsic::NoAliasDeclObjIdArg) == + Call.getArgOperand(Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg)), + "llvm.provenance.noalias objId arg must match with " + "llvm.noalias.decl", + Call); + Assert((CB->getArgOperand(Intrinsic::NoAliasDeclScopeArg) == + Call.getArgOperand(Intrinsic::ProvenanceNoAliasScopeArg)), + "llvm.provenance.noalias scope arg must match with " + "llvm.noalias.decl", + Call); + } + } + break; + } }; } Index: llvm/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/lib/Passes/PassBuilder.cpp +++ llvm/lib/Passes/PassBuilder.cpp @@ -143,6 +143,7 @@ #include "llvm/Transforms/Scalar/AnnotationRemarks.h" #include "llvm/Transforms/Scalar/BDCE.h" #include "llvm/Transforms/Scalar/CallSiteSplitting.h" +#include "llvm/Transforms/Scalar/ConnectNoAliasDecl.h" #include "llvm/Transforms/Scalar/ConstantHoisting.h" #include "llvm/Transforms/Scalar/ConstraintElimination.h" #include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h" @@ -195,6 +196,7 @@ #include "llvm/Transforms/Scalar/NaryReassociate.h" #include "llvm/Transforms/Scalar/NewGVN.h" #include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h" +#include "llvm/Transforms/Scalar/PropagateAndConvertNoAlias.h" #include "llvm/Transforms/Scalar/Reassociate.h" #include "llvm/Transforms/Scalar/Reg2Mem.h" #include "llvm/Transforms/Scalar/RewriteStatepointsForGC.h" Index: llvm/lib/Passes/PassBuilderPipelines.cpp =================================================================== --- llvm/lib/Passes/PassBuilderPipelines.cpp +++ llvm/lib/Passes/PassBuilderPipelines.cpp @@ -75,6 +75,7 @@ #include "llvm/Transforms/Scalar/AnnotationRemarks.h" #include "llvm/Transforms/Scalar/BDCE.h" #include "llvm/Transforms/Scalar/CallSiteSplitting.h" +#include "llvm/Transforms/Scalar/ConnectNoAliasDecl.h" #include "llvm/Transforms/Scalar/ConstraintElimination.h" #include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h" #include "llvm/Transforms/Scalar/DFAJumpThreading.h" @@ -106,6 +107,7 @@ #include "llvm/Transforms/Scalar/MemCpyOptimizer.h" #include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h" #include "llvm/Transforms/Scalar/NewGVN.h" +#include "llvm/Transforms/Scalar/PropagateAndConvertNoAlias.h" #include "llvm/Transforms/Scalar/Reassociate.h" #include "llvm/Transforms/Scalar/SCCP.h" #include "llvm/Transforms/Scalar/SROA.h" @@ -240,6 +242,8 @@ FunctionPassManager FPM; + FPM.addPass(ConnectNoAliasDeclPass()); // Do this before SROA + // Form SSA out of local memory accesses after breaking apart aggregates into // scalars. FPM.addPass(SROAPass()); @@ -247,6 +251,10 @@ // Catch trivial redundancies FPM.addPass(EarlyCSEPass(true /* Enable mem-ssa. */)); + // Propagate and Convert noalias intrinsics as early as possible. + // But do it after SROA and EarlyCSE ! + FPM.addPass(PropagateAndConvertNoAliasPass()); + // Hoisting of scalars and load expressions. FPM.addPass(SimplifyCFGPass()); FPM.addPass(InstCombinePass()); @@ -332,9 +340,15 @@ /*UseMemorySSA=*/false, /*UseBlockFrequencyInfo=*/false)); + FPM.addPass(ConnectNoAliasDeclPass()); // Do this before SROA + // Delete small array after loop unroll. FPM.addPass(SROAPass()); + // Propagate and Convert noalias intrinsics as early as possible. + // But do it after SROA and EarlyCSE ! + FPM.addPass(PropagateAndConvertNoAliasPass()); + // Specially optimize memory movement as it doesn't look like dataflow in SSA. FPM.addPass(MemCpyOptPass()); @@ -381,12 +395,19 @@ FunctionPassManager FPM; + FPM.addPass(ConnectNoAliasDeclPass()); // Do this before SROA + // Form SSA out of local memory accesses after breaking apart aggregates into // scalars. FPM.addPass(SROAPass()); // Catch trivial redundancies FPM.addPass(EarlyCSEPass(true /* Enable mem-ssa. */)); + + // Propagate and Convert noalias intrinsics as early as possible. + // But do it after SROA and EarlyCSE ! + FPM.addPass(PropagateAndConvertNoAliasPass()); + if (EnableKnowledgeRetention) FPM.addPass(AssumeSimplifyPass()); @@ -507,9 +528,15 @@ /*UseMemorySSA=*/false, /*UseBlockFrequencyInfo=*/false)); + FPM.addPass(ConnectNoAliasDeclPass()); // Do this before SROA + // Delete small array after loop unroll. FPM.addPass(SROAPass()); + // Propagate and Convert noalias intrinsics as early as possible. + // But do it after SROA and EarlyCSE ! + FPM.addPass(PropagateAndConvertNoAliasPass()); + // The matrix extension can introduce large vector operations early, which can // benefit from running vector-combine early on. if (EnableMatrix) @@ -537,6 +564,10 @@ FPM.addPass(InstCombinePass()); invokePeepholeEPCallbacks(FPM, Level); + // Late noalias intrinsics cleanup + FPM.addPass(ConnectNoAliasDeclPass()); + FPM.addPass(PropagateAndConvertNoAliasPass()); + // Re-consider control flow based optimizations after redundancy elimination, // redo DCE, etc. if (EnableDFAJumpThreading && Level.getSizeLevel() == 0) @@ -600,8 +631,15 @@ CGSCCPassManager &CGPipeline = MIWP.getPM(); FunctionPassManager FPM; + FPM.addPass(ConnectNoAliasDeclPass()); // Do this before SROA + FPM.addPass(SROAPass()); FPM.addPass(EarlyCSEPass()); // Catch trivial redundancies. + + // Propagate and Convert as early as possible. + // But do it after SROA and EarlyCSE ! + FPM.addPass(PropagateAndConvertNoAliasPass()); + FPM.addPass(SimplifyCFGPass()); // Merge & remove basic blocks. FPM.addPass(InstCombinePass()); // Combine silly sequences. invokePeepholeEPCallbacks(FPM, Level); @@ -813,8 +851,15 @@ // Compare/branch metadata may alter the behavior of passes like SimplifyCFG. EarlyFPM.addPass(LowerExpectIntrinsicPass()); EarlyFPM.addPass(SimplifyCFGPass()); + EarlyFPM.addPass(ConnectNoAliasDeclPass()); // Do this before SROA + EarlyFPM.addPass(SROAPass()); EarlyFPM.addPass(EarlyCSEPass()); + + // Propagate and Convert as early as possible. + // But do it after SROA and EarlyCSE ! + EarlyFPM.addPass(PropagateAndConvertNoAliasPass()); + EarlyFPM.addPass(CoroEarlyPass()); if (Level == OptimizationLevel::O3) EarlyFPM.addPass(CallSiteSplittingPass()); @@ -1555,9 +1600,15 @@ PGOOpt->ProfileRemappingFile); } + FPM.addPass(ConnectNoAliasDeclPass()); // Do this before SROA + // Break up allocas FPM.addPass(SROAPass()); + // Propagate and Convert as early as possible. + // But do it after SROA and EarlyCSE ! + FPM.addPass(PropagateAndConvertNoAliasPass()); + // LTO provides additional opportunities for tailcall elimination due to // link-time inlining, and visibility of nocapture attribute. FPM.addPass(TailCallElimPass()); Index: llvm/lib/Passes/PassRegistry.def =================================================================== --- llvm/lib/Passes/PassRegistry.def +++ llvm/lib/Passes/PassRegistry.def @@ -238,8 +238,10 @@ FUNCTION_PASS("bounds-checking", BoundsCheckingPass()) FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass()) FUNCTION_PASS("callsite-splitting", CallSiteSplittingPass()) +FUNCTION_PASS("connect-noaliasdecl", ConnectNoAliasDeclPass()) FUNCTION_PASS("consthoist", ConstantHoistingPass()) FUNCTION_PASS("constraint-elimination", ConstraintEliminationPass()) +FUNCTION_PASS("convert-noalias", PropagateAndConvertNoAliasPass()) FUNCTION_PASS("chr", ControlHeightReductionPass()) FUNCTION_PASS("coro-early", CoroEarlyPass()) FUNCTION_PASS("coro-elide", CoroElidePass()) Index: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -162,7 +162,9 @@ for (User *U : make_early_inc_range(I->users())) { Instruction *UI = cast(U); Type *SrcTy; - if (LoadInst *L = dyn_cast(UI)) + IndicesVector Indices; + LoadInst *L = dyn_cast(UI); + if (L) SrcTy = L->getType(); else SrcTy = cast(UI)->getSourceElementType(); @@ -172,19 +174,20 @@ continue; } - IndicesVector Indices; - Indices.reserve(UI->getNumOperands() - 1); - // Since loads will only have a single operand, and GEPs only a single - // non-index operand, this will record direct loads without any indices, - // and gep+loads with the GEP indices. - for (const Use &I : llvm::drop_begin(UI->operands())) - Indices.push_back(cast(I)->getSExtValue()); - // GEPs with a single 0 index can be merged with direct loads - if (Indices.size() == 1 && Indices.front() == 0) - Indices.clear(); + if (L == nullptr) { // not a direct load (loads can have 2 operands) + Indices.reserve(UI->getNumOperands() - 1); + // Since loads will only have a single operand, and GEPs only a single + // non-index operand, this will record direct loads without any indices, + // and gep+loads with the GEP indices. + for (const Use &I : llvm::drop_begin(UI->operands())) + Indices.push_back(cast(I)->getSExtValue()); + // GEPs with a single 0 index can be merged with direct loads + if (Indices.size() == 1 && Indices.front() == 0) + Indices.clear(); + } ArgIndices.insert(std::make_pair(SrcTy, Indices)); LoadInst *OrigLoad; - if (LoadInst *L = dyn_cast(UI)) + if (L) OrigLoad = L; else // Take any load, we will use it only to update Alias Analysis @@ -312,7 +315,9 @@ IRB.CreateLoad(OrigLoad->getType(), V, V->getName() + ".val"); newLoad->setAlignment(OrigLoad->getAlign()); // Transfer the AA info too. - newLoad->setAAMetadata(OrigLoad->getAAMetadata()); + AAMDNodes AAInfo = OrigLoad->getAAMetadata(); + newLoad->setAAMetadata(AAInfo); + newLoad->copyOptionalPtrProvenance(OrigLoad); Args.push_back(newLoad); ArgAttrVec.push_back(AttributeSet()); Index: llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp =================================================================== --- llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -207,7 +207,9 @@ } NewCB->setCallingConv(CB->getCallingConv()); NewCB->setAttributes(PAL); - NewCB->copyMetadata(*CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg}); + NewCB->copyMetadata(*CB, + {LLVMContext::MD_prof, LLVMContext::MD_dbg, + LLVMContext::MD_noalias, LLVMContext::MD_alias_scope}); Args.clear(); @@ -950,7 +952,9 @@ } NewCB->setCallingConv(CB.getCallingConv()); NewCB->setAttributes(NewCallPAL); - NewCB->copyMetadata(CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg}); + NewCB->copyMetadata(CB, + {LLVMContext::MD_prof, LLVMContext::MD_dbg, + LLVMContext::MD_noalias, LLVMContext::MD_alias_scope}); Args.clear(); ArgAttrVec.clear(); Index: llvm/lib/Transforms/IPO/FunctionAttrs.cpp =================================================================== --- llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -1215,6 +1215,12 @@ case Instruction::Call: case Instruction::Invoke: { CallBase &CB = cast(*RVI); + if (CB.getIntrinsicID() == Intrinsic::noalias_arg_guard || + CB.getIntrinsicID() == Intrinsic::noalias_copy_guard) { + // Look through a noalias arg/copy guard + FlowsToReturn.insert(RVI->getOperand(0)); + continue; + } Function *Callee = CB.getCalledFunction(); // A call to a node within the SCC is assumed to return null until // proven otherwise Index: llvm/lib/Transforms/IPO/GlobalOpt.cpp =================================================================== --- llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -208,11 +208,16 @@ SmallVector, 32> Dead; // Constants can't be pointers to dynamically allocated memory. - for (User *U : llvm::make_early_inc_range(GV->users())) { + for (Value::user_iterator UI = GV->user_begin(), E = GV->user_end(); + UI != E;) { + User *U = *UI++; if (StoreInst *SI = dyn_cast(U)) { Value *V = SI->getValueOperand(); if (isa(V)) { Changed = true; + // skip potential second use from ptr_provenance before the erase + if ((UI != E) && (*UI == SI)) + UI++; SI->eraseFromParent(); } else if (Instruction *I = dyn_cast(V)) { if (I->hasOneUse()) @@ -849,11 +854,16 @@ bool AllNonStoreUsesGone = true; // Replace all uses of loads with uses of uses of the stored value. - for (User *GlobalUser : llvm::make_early_inc_range(GV->users())) { + for (Value::user_iterator UI = GV->user_begin(), E = GV->user_end(); + UI != E;) { + User *GlobalUser = *UI++; if (LoadInst *LI = dyn_cast(GlobalUser)) { Changed |= OptimizeAwayTrappingUsesOfValue(LI, LV); // If we were able to delete all uses of the loads if (LI->use_empty()) { + // skip potential second use from ptr_provenance before the erase + if ((UI != E) && (*UI == LI)) + UI++; LI->eraseFromParent(); Changed = true; } else { Index: llvm/lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -332,8 +332,15 @@ // Compare/branch metadata may alter the behavior of passes like SimplifyCFG. FPM.add(createLowerExpectIntrinsicPass()); FPM.add(createCFGSimplificationPass()); + FPM.add(createConnectNoAliasDeclPass()); // Do this before SROA FPM.add(createSROAPass()); FPM.add(createEarlyCSEPass()); + + // Propagate and Convert as early as possible. + // But do it after SROA! + FPM.add(createPropagateAndConvertNoAliasPass()); + if (VerifyOutput) + FPM.add(createVerifierPass()); } // Do PGO instrumentation generation or use pass as the option specified. @@ -363,8 +370,16 @@ IP.HintThreshold = SizeLevel > 0 ? PreInlineThreshold : 325; MPM.add(createFunctionInliningPass(IP)); + MPM.add(createConnectNoAliasDeclPass()); // Do this before SROA MPM.add(createSROAPass()); MPM.add(createEarlyCSEPass()); // Catch trivial redundancies + + // Propagate and Convert as early as possible. + // But do it after SROA and EarlyCSE ! + MPM.add(createPropagateAndConvertNoAliasPass()); + if (VerifyOutput) + MPM.add(createVerifierPass()); + MPM.add(createCFGSimplificationPass()); // Merge & remove BBs MPM.add(createInstructionCombiningPass()); // Combine silly seq's addExtensionsToPM(EP_Peephole, MPM); @@ -392,6 +407,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses( legacy::PassManagerBase &MPM) { // Start of function pass. + MPM.add(createConnectNoAliasDeclPass()); // Do this before SROA // Break up aggregate allocas, using SSAUpdater. assert(OptLevel >= 1 && "Calling function optimizer with no optimization level!"); MPM.add(createSROAPass()); @@ -399,6 +415,12 @@ if (EnableKnowledgeRetention) MPM.add(createAssumeSimplifyPass()); + // Propagate and Convert as early as possible. + // But do it after SROA and EarlyCSE ! + MPM.add(createPropagateAndConvertNoAliasPass()); + if (VerifyOutput) + MPM.add(createVerifierPass()); + if (OptLevel > 1) { if (EnableGVNHoist) MPM.add(createGVNHoistPass()); @@ -486,9 +508,17 @@ addExtensionsToPM(EP_LoopOptimizerEnd, MPM); // This ends the loop pass pipelines. + MPM.add(createConnectNoAliasDeclPass()); // Do this before SROA + // Break up allocas that may now be splittable after loop unrolling. MPM.add(createSROAPass()); + // Propagate and Convert as early as possible. + // But do it after SROA! + MPM.add(createPropagateAndConvertNoAliasPass()); + if (VerifyOutput) + MPM.add(createVerifierPass()); + if (OptLevel > 1) { MPM.add(createMergedLoadStoreMotionPass()); // Merge ld/st in diamonds MPM.add(NewGVN ? createNewGVNPass() @@ -508,6 +538,14 @@ // opened up by them. MPM.add(createInstructionCombiningPass()); addExtensionsToPM(EP_Peephole, MPM); + + MPM.add(createConnectNoAliasDeclPass()); // late cleanup + // Propagate and Convert as early as possible. + // But do it after SROA! + MPM.add(createPropagateAndConvertNoAliasPass()); + if (VerifyOutput) + MPM.add(createVerifierPass()); + if (OptLevel > 1) { if (EnableDFAJumpThreading && SizeLevel == 0) MPM.add(createDFAJumpThreadingPass()); @@ -799,6 +837,12 @@ MPM.add(Inliner); Inliner = nullptr; RunInliner = true; + + // Propagate and Convert as early as possible. + // But do it after SROA! + MPM.add(createPropagateAndConvertNoAliasPass()); + if (VerifyOutput) + MPM.add(createVerifierPass()); } // Infer attributes on declarations, call sites, arguments, etc. for an SCC. @@ -1077,6 +1121,12 @@ if (RunInliner) { PM.add(Inliner); Inliner = nullptr; + + // Propagate and Convert as early as possible. + // But do it after SROA! + PM.add(createPropagateAndConvertNoAliasPass()); + if (VerifyOutput) + PM.add(createVerifierPass()); } PM.add(createPruneEHPass()); // Remove dead EH info. @@ -1107,9 +1157,17 @@ addExtensionsToPM(EP_Peephole, PM); PM.add(createJumpThreadingPass(/*FreezeSelectCond*/ true)); + PM.add(createConnectNoAliasDeclPass()); // Do this before SROA + // Break up allocas PM.add(createSROAPass()); + // Propagate and Convert as early as possible. + // But do it after SROA! + PM.add(createPropagateAndConvertNoAliasPass()); + if (VerifyOutput) + PM.add(createVerifierPass()); + // LTO provides additional opportunities for tailcall elimination due to // link-time inlining, and visibility of nocapture attribute. if (OptLevel > 1) Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2400,6 +2400,22 @@ return V.getValue(); break; } + case Intrinsic::noalias_decl: { + Value *Op0 = II->getOperand(0); + Value *BaseOp0 = Op0->stripPointerCasts(); + if (Op0 != BaseOp0) { + auto *NewNoAlias = Builder.CreateNoAliasDeclaration( + BaseOp0, II->getOperand(1), II->getOperand(2)); + // bwaahh seems we need to do everything ourselves ? + II->replaceAllUsesWith(NewNoAlias); + Worklist.remove(II); + II->eraseFromParent(); + MadeIRChange = true; + + return nullptr; + } + break; + } } // Some intrinsics (like experimental_gc_statepoint) can be used in invoke // context, so it is handled in visitCallBase and we should trigger it. Index: llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -480,10 +480,20 @@ NewPtr->getType() == NewPtrTy)) NewPtr = Builder.CreateBitCast(Ptr, NewPtrTy); + Value *NewProvenancePtr = nullptr; + if (LI.hasNoaliasProvenanceOperand()) { + NewProvenancePtr = Builder.CreateBitCast(LI.getNoaliasProvenanceOperand(), + NewTy->getPointerTo(AS)); + } + LoadInst *NewLoad = Builder.CreateAlignedLoad( NewTy, NewPtr, LI.getAlign(), LI.isVolatile(), LI.getName() + Suffix); NewLoad->setAtomic(LI.getOrdering(), LI.getSyncScopeID()); copyMetadataForLoad(*NewLoad, LI); + if (LI.hasNoaliasProvenanceOperand()) { + assert(NewProvenancePtr); + NewLoad->setNoaliasProvenanceOperand(NewProvenancePtr); + } return NewLoad; } @@ -500,6 +510,12 @@ SmallVector, 8> MD; SI.getAllMetadata(MD); + Value *NewProvenancePtr = nullptr; + if (SI.hasNoaliasProvenanceOperand()) { + NewProvenancePtr = IC.Builder.CreateBitCast( + SI.getNoaliasProvenanceOperand(), V->getType()->getPointerTo(AS)); + } + StoreInst *NewStore = IC.Builder.CreateAlignedStore( V, IC.Builder.CreateBitCast(Ptr, V->getType()->getPointerTo(AS)), SI.getAlign(), SI.isVolatile()); @@ -541,6 +557,11 @@ } } + if (SI.hasNoaliasProvenanceOperand()) { + assert(NewProvenancePtr); + NewStore->setNoaliasProvenanceOperand(NewProvenancePtr); + } + return NewStore; } @@ -677,7 +698,9 @@ ST->getElementType(i), Ptr, commonAlignment(Align, SL->getElementOffset(i)), Name + ".unpack"); // Propagate AA metadata. It'll still be valid on the narrowed load. - L->setAAMetadata(LI.getAAMetadata()); + AAMDNodes AAMD = LI.getAAMetadata(); + L->setAAMetadata(AAMD); + L->copyOptionalPtrProvenance(&LI); V = IC.Builder.CreateInsertValue(V, L, i); } @@ -722,7 +745,9 @@ auto *L = IC.Builder.CreateAlignedLoad(AT->getElementType(), Ptr, commonAlignment(Align, Offset), Name + ".unpack"); - L->setAAMetadata(LI.getAAMetadata()); + AAMDNodes AAMD = LI.getAAMetadata(); + L->setAAMetadata(AAMD); + L->copyOptionalPtrProvenance(&LI); V = IC.Builder.CreateInsertValue(V, L, i); Offset += EltSize; } @@ -940,6 +965,15 @@ Instruction *InstCombinerImpl::visitLoadInst(LoadInst &LI) { Value *Op = LI.getOperand(0); + if (LI.hasNoaliasProvenanceOperand()) { + if (LI.getNoaliasProvenanceOperand() == LI.getPointerOperand() || + isa(LI.getNoaliasProvenanceOperand())) { + // degenerated ptr_provenance + LI.removeNoaliasProvenanceOperand(); + return &LI; + } + } + // Try to canonicalize the loaded type. if (Instruction *Res = combineLoadToOperationType(*this, LI)) return Res; @@ -1198,8 +1232,10 @@ AddrName); auto *Val = IC.Builder.CreateExtractValue(V, i, EltName); auto EltAlign = commonAlignment(Align, SL->getElementOffset(i)); - llvm::Instruction *NS = IC.Builder.CreateAlignedStore(Val, Ptr, EltAlign); - NS->setAAMetadata(SI.getAAMetadata()); + llvm::StoreInst *NS = IC.Builder.CreateAlignedStore(Val, Ptr, EltAlign); + AAMDNodes AAMD = SI.getAAMetadata(); + NS->setAAMetadata(AAMD); + NS->copyOptionalPtrProvenance(&SI); } return true; @@ -1244,8 +1280,10 @@ AddrName); auto *Val = IC.Builder.CreateExtractValue(V, i, EltName); auto EltAlign = commonAlignment(Align, Offset); - Instruction *NS = IC.Builder.CreateAlignedStore(Val, Ptr, EltAlign); - NS->setAAMetadata(SI.getAAMetadata()); + StoreInst *NS = IC.Builder.CreateAlignedStore(Val, Ptr, EltAlign); + AAMDNodes AAMD = SI.getAAMetadata(); + NS->setAAMetadata(AAMD); + NS->copyOptionalPtrProvenance(&SI); Offset += EltSize; } @@ -1340,6 +1378,15 @@ Value *Val = SI.getOperand(0); Value *Ptr = SI.getOperand(1); + if (SI.hasNoaliasProvenanceOperand()) { + if (SI.getNoaliasProvenanceOperand() == SI.getPointerOperand() || + isa(SI.getNoaliasProvenanceOperand())) { + // degenerated ptr_provenance + SI.removeNoaliasProvenanceOperand(); + return &SI; + } + } + // Try to canonicalize the stored type. if (combineStoreToValueType(*this, SI)) return eraseInstFromFunction(SI); @@ -1557,8 +1604,17 @@ // If the two stores had AA tags, merge them. AAMDNodes AATags = SI.getAAMetadata(); - if (AATags) - NewSI->setAAMetadata(AATags.merge(OtherStore->getAAMetadata())); + if (AATags) { + AATags = AATags.merge(OtherStore->getAAMetadata()); + NewSI->setAAMetadata(AATags); + } + + Optional CommonPtrProvenance = SI.getOptionalPtrProvenance(); + CommonPtrProvenance = + mergePtrProvenance(CommonPtrProvenance, + OtherStore->getOptionalPtrProvenance()); + if (CommonPtrProvenance) + NewSI->setNoaliasProvenanceOperand(CommonPtrProvenance.getValue()); // Nuke the old stores. eraseInstFromFunction(SI); Index: llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp +++ llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp @@ -721,11 +721,8 @@ new LoadInst(FirstLI->getType(), NewPN, "", isVolatile, LoadAlignment); unsigned KnownIDs[] = { - LLVMContext::MD_tbaa, LLVMContext::MD_range, LLVMContext::MD_invariant_load, - LLVMContext::MD_alias_scope, - LLVMContext::MD_noalias, LLVMContext::MD_nonnull, LLVMContext::MD_align, LLVMContext::MD_dereferenceable, @@ -737,14 +734,22 @@ NewLI->setMetadata(ID, FirstLI->getMetadata(ID)); // Add all operands to the new PHI and combine TBAA metadata. + AAMDNodes AAInfo = FirstLI->getAAMetadata(); + Optional CommonPtrProvenance = FirstLI->getOptionalPtrProvenance(); for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { LoadInst *LI = cast(PN.getIncomingValue(i)); combineMetadata(NewLI, LI, KnownIDs, true); + AAInfo = AAInfo.merge(LI->getAAMetadata()); + CommonPtrProvenance = mergePtrProvenance(CommonPtrProvenance, + LI->getOptionalPtrProvenance()); Value *NewInVal = LI->getOperand(0); if (NewInVal != InVal) InVal = nullptr; NewPN->addIncoming(NewInVal, PN.getIncomingBlock(i)); } + NewLI->setAAMetadata(AAInfo); + if (CommonPtrProvenance) + NewLI->setNoaliasProvenanceOperand(CommonPtrProvenance.getValue()); if (InVal) { // The new PHI unions all of the same values together. This is really Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2594,6 +2594,7 @@ case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::objectsize: + case Intrinsic::noalias_decl: Users.emplace_back(I); continue; case Intrinsic::launder_invariant_group: @@ -3170,13 +3171,26 @@ Builder.SetInsertPoint(L); Value *GEP = Builder.CreateInBoundsGEP(L->getType(), L->getPointerOperand(), Indices); - Instruction *NL = Builder.CreateLoad(EV.getType(), GEP); + LoadInst *NL = Builder.CreateLoad(EV.getType(), GEP); // Whatever aliasing information we had for the orignal load must also // hold for the smaller load, so propagate the annotations. - NL->setAAMetadata(L->getAAMetadata()); + AAMDNodes Nodes = L->getAAMetadata(); + NL->setAAMetadata(Nodes); + NL->copyOptionalPtrProvenance(L); // Returning the load directly will cause the main loop to insert it in - // the wrong spot, so use replaceInstUsesWith(). - return replaceInstUsesWith(EV, NL); + // the wrong spot, so use ReplaceInstUsesWith(). + { + for (auto mdtag : + {LLVMContext::MD_dbg, LLVMContext::MD_prof, LLVMContext::MD_fpmath, + LLVMContext::MD_tbaa_struct, LLVMContext::MD_invariant_load, + LLVMContext::MD_nontemporal, + LLVMContext::MD_mem_parallel_loop_access}) { + if (auto *MD = L->getMetadata(mdtag)) { + NL->setMetadata(mdtag, MD); + } + } + return replaceInstUsesWith(EV, NL); + } } // We could simplify extracts from other values. Note that nested extracts may // already be simplified implicitly by the above: extract (extract (insert) ) Index: llvm/lib/Transforms/Scalar/CMakeLists.txt =================================================================== --- llvm/lib/Transforms/Scalar/CMakeLists.txt +++ llvm/lib/Transforms/Scalar/CMakeLists.txt @@ -4,6 +4,7 @@ AnnotationRemarks.cpp BDCE.cpp CallSiteSplitting.cpp + ConnectNoAliasDecl.cpp ConstantHoisting.cpp ConstraintElimination.cpp CorrelatedValuePropagation.cpp @@ -61,6 +62,7 @@ NewGVN.cpp PartiallyInlineLibCalls.cpp PlaceSafepoints.cpp + PropagateAndConvertNoAlias.cpp Reassociate.cpp Reg2Mem.cpp RewriteStatepointsForGC.cpp Index: llvm/lib/Transforms/Scalar/ConnectNoAliasDecl.cpp =================================================================== --- /dev/null +++ llvm/lib/Transforms/Scalar/ConnectNoAliasDecl.cpp @@ -0,0 +1,114 @@ +//===- ConnectNoAliasDecl.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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This pass connects provenance.noalias intrinsics to the corresponding +/// llvm.noalias.decl, based on the alloca of the pointer. +/// +//===----------------------------------------------------------------------===// +// +// When the original restrict declaration is not directly available, +// llvm.noalias, llvm.provenance.noalias and llvm.noalias.copy.guard can be +// associated with an 'unknown' (out of function) noalias scope. After certain +// optimizations, like SROA, inlining, ... it is possible that a +// llvm.noalias.decl is associated to an alloca, to which a llvm.noalias, +// llvm.provenance.noalias orllvm.noalias.copy.guard intrinsics is also +// associated. When the latter intrinsics are still refering to the 'unknown' +// scope, we can now refine the information by associating the llvm.noalias.decl +// and its information to the other noalias intrinsics that are depending on the +// same alloca. +// +// This pass will connect those llvm.noalias.decl to those +// llvm.noalias,llvm.provenance.noalias and llvm.noalias.copy.guard. It will +// also propagate the embedded information. +// +// This pass is best placed before SROA or PropagateAndConvertNoAlias. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Scalar/ConnectNoAliasDecl.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/IR/Dominators.h" +#include "llvm/InitializePasses.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils/Cloning.h" + +using namespace llvm; + +namespace { +class ConnectNoAliasDeclLegacyPass : public FunctionPass { +public: + static char ID; // Pass identification, replacement for typeid + ConnectNoAliasDeclLegacyPass() : FunctionPass(ID) { + initializeConnectNoAliasDeclLegacyPassPass( + *PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { + // FIXME: is all of this valid ? + AU.addPreserved(); + AU.addPreserved(); // FIXME: not sure this is + // valid. It ensures the same pass + // order as if this pass was not + // there + AU.addPreserved(); + AU.addRequiredTransitive(); + AU.setPreservesCFG(); + } + +private: + ConnectNoAliasDeclPass Impl; +}; +} // namespace + +char ConnectNoAliasDeclLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN( + ConnectNoAliasDeclLegacyPass, "connect-noaliasdecl", + "Connect llvm.noalias.decl", false, + false) // to llvm.noalias/llvm.provenance.noalias/llvm.noalias.copy.guard + // intrinsics +INITIALIZE_PASS_END( + ConnectNoAliasDeclLegacyPass, "connect-noaliasdecl", + "Connect llvm.noalias.decl", false, + false) // to llvm.noalias/llvm.provenance.noalias/llvm.noalias.copy.guard + // intrinsics + +bool ConnectNoAliasDeclLegacyPass::runOnFunction(Function &F) { + if (skipFunction(F)) + return false; + + return Impl.runImpl(F); +} + +namespace llvm { + +bool ConnectNoAliasDeclPass::runImpl(Function &F) { + return llvm::propagateAndConnectNoAliasDecl(&F); +} + +PreservedAnalyses ConnectNoAliasDeclPass::run(Function &F, + FunctionAnalysisManager &AM) { + bool Changed = runImpl(F); + + if (!Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve(); + //?? PA.preserve(); // FIXME: not sure this is valid, + // see above + + return PA; +} + +FunctionPass *createConnectNoAliasDeclPass() { + return new ConnectNoAliasDeclLegacyPass(); +} +} // namespace llvm Index: llvm/lib/Transforms/Scalar/EarlyCSE.cpp =================================================================== --- llvm/lib/Transforms/Scalar/EarlyCSE.cpp +++ llvm/lib/Transforms/Scalar/EarlyCSE.cpp @@ -1247,7 +1247,17 @@ << '\n'); AvailableValues.insert(CondI, ConstantInt::getTrue(BB->getContext())); } else - LLVM_DEBUG(dbgs() << "EarlyCSE skipping assumption: " << Inst << '\n'); + LLVM_DEBUG(dbgs() << "EarlyCSE skipping intrinsic: " << Inst << '\n'); + continue; + } + + // Likewise, noalias intrinsics don't actually write. + if (match(&Inst, m_Intrinsic()) || + match(&Inst, m_Intrinsic()) || + match(&Inst, m_Intrinsic()) || + match(&Inst, m_Intrinsic())) { + LLVM_DEBUG(dbgs() << "EarlyCSE skipping noalias intrinsic: " << Inst + << '\n'); continue; } Index: llvm/lib/Transforms/Scalar/GVN.cpp =================================================================== --- llvm/lib/Transforms/Scalar/GVN.cpp +++ llvm/lib/Transforms/Scalar/GVN.cpp @@ -1234,8 +1234,11 @@ // Transfer the old load's AA tags to the new load. AAMDNodes Tags = Load->getAAMetadata(); - if (Tags) + if (Tags) { NewLoad->setAAMetadata(Tags); + // Note: ptr_provenance propagation is not done here. A dependend + // provenance should be migrated first ! + } if (auto *MD = Load->getMetadata(LLVMContext::MD_invariant_load)) NewLoad->setMetadata(LLVMContext::MD_invariant_load, MD); Index: llvm/lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -1488,8 +1488,11 @@ LoadI->getOrdering(), LoadI->getSyncScopeID(), UnavailablePred->getTerminator()); NewVal->setDebugLoc(LoadI->getDebugLoc()); - if (AATags) + if (AATags) { NewVal->setAAMetadata(AATags); + // Note: ptr_provenance propagation is not done here. A dependend + // provenance should be migrated first ! + } AvailablePreds.emplace_back(UnavailablePred, NewVal); } @@ -2070,7 +2073,6 @@ // copy of the block 'NewBB'. If there are PHI nodes in the source basic // block, evaluate them to account for entry from PredBB. DenseMap ValueMapping; - // Clone the phi nodes of the source basic block into NewBB. The resulting // phi nodes are trivial since NewBB only has one predecessor, but SSAUpdater // might need to rewrite the operand of the cloned phi. @@ -2080,14 +2082,7 @@ ValueMapping[PN] = NewPN; } - // Clone noalias scope declarations in the threaded block. When threading a - // loop exit, we would otherwise end up with two idential scope declarations - // visible at the same time. - SmallVector NoAliasScopes; - DenseMap ClonedScopes; - LLVMContext &Context = PredBB->getContext(); - identifyNoAliasScopesToClone(BI, BE, NoAliasScopes); - cloneNoAliasScopes(NoAliasScopes, ClonedScopes, "thread", Context); + // Cloning noalias scopes is allowed and will refer to the same scope. // Clone the non-phi instructions of the source basic block into NewBB, // keeping track of the mapping and using it to remap operands in the cloned @@ -2096,8 +2091,18 @@ Instruction *New = BI->clone(); New->setName(BI->getName()); NewBB->getInstList().push_back(New); + // Also track the ptr_provenance + if (auto *SI = dyn_cast(BI)) { + if (SI->hasNoaliasProvenanceOperand()) + cast(New)->setNoaliasProvenanceOperand( + SI->getNoaliasProvenanceOperand()); + } else if (auto *LI = dyn_cast(BI)) { + if (LI->hasNoaliasProvenanceOperand()) + cast(New)->setNoaliasProvenanceOperand( + LI->getNoaliasProvenanceOperand()); + } + ValueMapping[&*BI] = New; - adaptNoAliasScopes(New, ClonedScopes, Context); // Remap operands to patch up intra-block references. for (unsigned i = 0, e = New->getNumOperands(); i != e; ++i) Index: llvm/lib/Transforms/Scalar/LICM.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LICM.cpp +++ llvm/lib/Transforms/Scalar/LICM.cpp @@ -1484,10 +1484,15 @@ } New = CallInst::Create(CI, OpBundles); - } else { + } else{ New = I.clone(); } + AAMDNodes AAMetadata = I.getAAMetadata(); + //@ FIXME: The other metadata should already be cloned ? + New->setAAMetadata(AAMetadata); + New->copyPtrProvenanceOperand(I); + ExitBlock.getInstList().insert(ExitBlock.getFirstInsertionPt(), New); if (!I.getName().empty()) New->setName(I.getName() + ".le"); @@ -1921,6 +1926,8 @@ NewSI->setDebugLoc(DL); if (AATags) NewSI->setAAMetadata(AATags); + // Note: ptr_provenance propagation is not done here. A dependend + // provenance should be migrated first ! MemoryAccess *MSSAInsertPoint = MSSAInsertPts[i]; MemoryAccess *NewMemAcc; @@ -2077,7 +2084,9 @@ if (SomePtr->getType() != ASIV->getType()) return false; - for (User *U : ASIV->users()) { + for (auto U_it = ASIV->user_begin(), U_it_end = ASIV->user_end(); + U_it != U_it_end; ++U_it) { + User *U = *U_it; // Ignore instructions that are outside the loop. Instruction *UI = dyn_cast(U); if (!UI || !CurLoop->contains(UI)) @@ -2086,6 +2095,9 @@ // If there is an non-load/store instruction in the loop, we can't promote // it. if (LoadInst *Load = dyn_cast(UI)) { + if (U_it.getUse().getOperandNo() == + Load->getNoaliasProvenanceOperandIndex()) + continue; if (!Load->isUnordered()) return false; @@ -2106,6 +2118,10 @@ Alignment = std::max(Alignment, InstAlignment); } } else if (const StoreInst *Store = dyn_cast(UI)) { + if (U_it.getUse().getOperandNo() == + Store->getNoaliasProvenanceOperandIndex()) + continue; + // Stores *of* the pointer are not interesting, only stores *to* the // pointer. if (UI->getOperand(1) != ASIV) @@ -2150,8 +2166,18 @@ Store->getPointerOperand(), Store->getValueOperand()->getType(), Store->getAlign(), MDL, Preheader->getTerminator(), DT, TLI); } - } else - return false; // Not a load or store. + } else { + // Not a load or store. + if (IntrinsicInst *II = dyn_cast(UI)) { + if (II->getIntrinsicID() == Intrinsic::provenance_noalias || + II->getIntrinsicID() == Intrinsic::noalias_arg_guard || + II->getIntrinsicID() == Intrinsic::noalias_copy_guard) { + // those must not block promotion. + continue; + } + } + return false; + } // Merge the AA tags. if (LoopUses.empty()) { @@ -2235,8 +2261,11 @@ PreheaderLoad->setOrdering(AtomicOrdering::Unordered); PreheaderLoad->setAlignment(Alignment); PreheaderLoad->setDebugLoc(DebugLoc()); - if (AATags) + if (AATags) { PreheaderLoad->setAAMetadata(AATags); + // Note: ptr_provenance propagation is not done here. A dependend provenance + // should be migrated first ! + } SSA.AddAvailableValue(Preheader, PreheaderLoad); MemoryAccess *PreheaderLoadMemoryAccess = MSSAU->createMemoryAccessInBB( Index: llvm/lib/Transforms/Scalar/PropagateAndConvertNoAlias.cpp =================================================================== --- /dev/null +++ llvm/lib/Transforms/Scalar/PropagateAndConvertNoAlias.cpp @@ -0,0 +1,1271 @@ +//===- PropagateAndConvertNoAlias.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 +// +//===----------------------------------------------------------------------===// +// +// This pass moves dependencies on llvm.noalias onto the ptr_provenance. +// It also introduces and propagates llvm.provenance.noalias and +// llvm.noalias.arg.guard intrinsics. +// +// It is best placed as early as possible, but after: SROA+EarlyCSE +// - SROA: SROA converts llvm.noalias.copy.guard into llvm.noalias +// - EarlyCSE helps in cleaning up some expressions, make our work here easier. +// +// And after inlining: inlining can also expose new llvm.noalias intrinsics and +// extra information about the dependencies. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Scalar/PropagateAndConvertNoAlias.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Dominators.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" +#include "llvm/InitializePasses.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" + +#include +#include + +using namespace llvm; + +#define DEBUG_TYPE "convert-noalias" + +namespace { + +class PropagateAndConvertNoAliasLegacyPass : public FunctionPass { +public: + static char ID; + explicit PropagateAndConvertNoAliasLegacyPass() : FunctionPass(ID), Impl() { + initializePropagateAndConvertNoAliasLegacyPassPass( + *PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override; + bool runOnFunction(Function &F) override; + + StringRef getPassName() const override { + return "Propagate and Convert Noalias intrinsics"; + } + +private: + PropagateAndConvertNoAliasPass Impl; +}; +} // namespace + +char PropagateAndConvertNoAliasLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN(PropagateAndConvertNoAliasLegacyPass, "convert-noalias", + "Propagate And Convert llvm.noalias intrinsics", false, + false) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_END(PropagateAndConvertNoAliasLegacyPass, "convert-noalias", + "Propagate And Convert llvm.noalias intrinsics", false, + false) + +void PropagateAndConvertNoAliasLegacyPass::getAnalysisUsage( + AnalysisUsage &AU) const { + AU.addPreserved(); + // FIXME: not sure the CallGraphWrapperPass is needed. It ensures the same + // pass order is kept as if the PropagateAndConvertNoAlias pass was not there. + AU.addPreserved(); + AU.addPreserved(); + AU.addRequiredTransitive(); +} + +bool PropagateAndConvertNoAliasLegacyPass::runOnFunction(Function &F) { + if (skipFunction(F)) + return false; + + return Impl.runImpl(F, getAnalysis().getDomTree()); +} + +namespace llvm { + +bool PropagateAndConvertNoAliasPass::runImpl(Function &F, DominatorTree &DT) { + return doit(F, DT); +} + +FunctionPass *createPropagateAndConvertNoAliasPass() { + return new PropagateAndConvertNoAliasLegacyPass(); +} + +PreservedAnalyses +PropagateAndConvertNoAliasPass::run(Function &F, FunctionAnalysisManager &AM) { + bool Changed = runImpl(F, AM.getResult(F)); + + if (!Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve(); + // FIXME: not sure this is valid: + //?? PA.preserve(); // See above + + return PA; +} + +typedef SmallVector ProvenanceWorklist; +typedef SmallVector DepsVector; +typedef std::map I2Deps; +typedef SmallPtrSet InstructionSet; +typedef SmallPtrSet BasicBlockSet; + +// Analyse and propagate the instructions that need provenances: +// - InstructionsForProvenance: instructions that need a provenance +// representation +// - at entry: (A) +// -- llvm.noalias -> llvm.provenance.noalias +// -- llvm.noalias.arg.guard a, prov_a -> prov_a +// +// - during propagation: (B) +// -- select a, b, c -> select a, prov_b, prov_c +// -- PHI a, b,... -> PHI prov_a, prov_b, ... +// +// - Handled: Instructions that have been investigated. The Deps side refers to +// the provenance dependency. (C) +// -- a nullptr indicates that the normal dependency must be used for that +// operand +// -- an I indictates that the provenance representation of I must be used for +// that operand +// +// The algorithm: +// - We start from the llvm.noalias and llvm.noalias.arg.guard instructions +// - We go over their users, and check if they are special or not +// -- special users need a provenance representation and are annotated as such +// in 'Handled' (non-empty Dep) +// -- normal instructions are a passthrough, and are annotated with an empty Dep +// in 'Handled' (I->{}) +// -- some instructions stop the recursion: +// --- ICmp +// --- first arg of select +// --- llvm.provenance.noalias, llvm.noalias +// +// After the analysis, 'Handled' contains an overview of all instructions that +// depend on (A) +// - those instructions that were seen, but ignored otherwise have no +// dependencies (I -> {} ) +// - instructions that refer to one ore more provenances have explicit +// dependencies. (I -> { op0, op1, op2, ... }) +// -- if opX == nullptr -> not a real ptr_provenance dependency +// -- if opX == someI : +// ---- if someI points to an instruction in Handled, it must be one of the +// instructions that have a provenance representation +// ---- otherwise, it points to a not-handle plain dependency (coming from a +// noalias.arg.guard) +static void propagateInstructionsForProvenance( + ProvenanceWorklist &InstructionsForProvenance, I2Deps &Handled, + ProvenanceWorklist &out_CreationList, InstructionSet &ProvenancePHIs, + BasicBlockSet &DeadBasicBlocks) { + auto updateMatchingOperands = [](Instruction *U, Instruction *I, + DepsVector &Deps, Instruction *I4SC) { + assert(U->getNumOperands() == Deps.size()); + auto it = Deps.begin(); + for (Value *UOp : U->operands()) { + if (UOp == I) { + assert(*it == nullptr || *it == I4SC); + *it = I4SC; + } + ++it; + } + }; + + while (!InstructionsForProvenance.empty()) { + Instruction *I4SC = InstructionsForProvenance.pop_back_val(); + LLVM_DEBUG(llvm::dbgs() + << "-- Propagating provenance instruction: " << *I4SC << "\n"); + if (DeadBasicBlocks.count(I4SC->getParent())) { + LLVM_DEBUG(llvm::dbgs() << "--- Skipped - dead basic block\n"); + continue; + } + SmallVector WorkList = {I4SC}; + if (auto *CB = dyn_cast(I4SC)) { + if (CB->getIntrinsicID() == Intrinsic::noalias_arg_guard) { + // llvm.noalias.arg.guard: delegate to ptr_provenance (operand 1) + Handled.insert(I2Deps::value_type(I4SC, {})); + // no need to add to out_CreationList + + assert(!isa(I4SC->getOperand(0)) && + !isa(I4SC->getOperand(1)) && + "Degenerated case must have been resolved already"); + assert(I4SC->getOperand(0) != I4SC->getOperand(1) && + "Degenerated case must have been resolved already"); + + I4SC = dyn_cast(I4SC->getOperand(1)); + if (I4SC == nullptr) { + // Provenance became a constant ? Then the arg guard is not needed + // any more and there is nothing to propagate + continue; + } + } + } + while (!WorkList.empty()) { + Instruction *I = WorkList.pop_back_val(); + LLVM_DEBUG(llvm::dbgs() << "-- checking:" << *I << "\n"); + if (DeadBasicBlocks.count(I->getParent())) { + LLVM_DEBUG(llvm::dbgs() << "--- skipped - dead basic block\n"); + continue; + } + bool isPtrToInt = isa(I); + for (auto &UOp : I->uses()) { + auto *U_ = UOp.getUser(); + LLVM_DEBUG(llvm::dbgs() << "--- used by:" << *U_ + << ", operand:" << UOp.getOperandNo() << "\n"); + Instruction *U = dyn_cast(U_); + if (U == nullptr) + continue; + + // Only see through a ptr2int if it used by a int2ptr + if (isPtrToInt && !isa(U)) + continue; + + if (isa(U)) { + // ======================================== select -> { lhs, rhs } + bool MatchesOp1 = (U->getOperand(1) == I); + bool MatchesOp2 = (U->getOperand(2) == I); + + if (MatchesOp1 || MatchesOp2) { + auto HI = Handled.insert(I2Deps::value_type(U, {nullptr, nullptr})); + if (HI.second) + out_CreationList.push_back(U); + if (MatchesOp1) { + HI.first->second[0] = I4SC; + } + if (MatchesOp2) { + HI.first->second[1] = I4SC; + } + if (HI.second) { + InstructionsForProvenance.push_back(U); + } + } + } else if (isa(U)) { + // ======================================== load -> { ptr } + if (UOp.getOperandNo() == + LoadInst::getNoaliasProvenanceOperandIndex()) + continue; // tracking on provenance -> ignore + + auto HI = Handled.insert(I2Deps::value_type(U, {I4SC})); + if (HI.second) + out_CreationList.push_back(U); + assert(U->getOperand(0) == I); + if (HI.second) { + // continue + } + } else if (isa(U)) { + // ======================================== store -> { val, ptr } + if (UOp.getOperandNo() == + StoreInst::getNoaliasProvenanceOperandIndex()) + continue; // tracking on provenance -> ignore + + // also track if we are storing a restrict annotated pointer value... + // This might provide useful information about 'escaping pointers' + bool MatchesOp0 = (U->getOperand(0) == I); + bool MatchesOp1 = (U->getOperand(1) == I); + + if (MatchesOp0 || MatchesOp1) { + auto HI = Handled.insert(I2Deps::value_type(U, {nullptr, nullptr})); + if (HI.second) + out_CreationList.push_back(U); + if (MatchesOp0) { + HI.first->second[0] = I4SC; + } + if (MatchesOp1) { + HI.first->second[1] = I4SC; + } + } + } else if (isa(U)) { + // ======================================== insertvalue -> { val } + // track for injecting llvm.noalias.arg.guard + assert(U->getOperand(1) == I); + // need to introduce a guard + auto HI = Handled.insert(I2Deps::value_type(U, {I4SC})); + if (HI.second) + out_CreationList.push_back(U); + } else if (isa(U)) { + // ======================================== ptr2int -> { val } + // track for injecting llvm.noalias.arg.guard + assert(U->getOperand(0) == I); + // need to introduce a guard + auto HI = Handled.insert(I2Deps::value_type(U, {I4SC})); + if (HI.second) + out_CreationList.push_back(U); + } else if (isa(U)) { + auto HI = Handled.insert(I2Deps::value_type(U, {I4SC})); + if (HI.second) + out_CreationList.push_back(U); + } else if (isa(U)) { + // ======================================== PHI -> { ..... } + PHINode *PU = cast(U); + auto HI = Handled.insert(I2Deps::value_type(U, {})); + if (HI.second) { + HI.first->second.resize(U->getNumOperands(), nullptr); + if (ProvenancePHIs.count(U) == 0) { + // This is a normal PHI, consider it for propagation + InstructionsForProvenance.push_back(U); + } + if (U->getNumOperands()) + out_CreationList.push_back(U); + } + updateMatchingOperands(PU, I, HI.first->second, I4SC); + } else if (auto *CS = dyn_cast(U)) { + // =============================== call/invoke/intrinsic -> { ...... } + + // NOTES: + // - we always block at a call... + // - the known intrinsics should not have any extra annotations + switch (CS->getIntrinsicID()) { + case Intrinsic::provenance_noalias: + case Intrinsic::noalias: { + bool MatchesOp0 = (U->getOperand(0) == I); + bool MatchesOpP = + (U->getOperand(Intrinsic::NoAliasIdentifyPArg) == I); + static_assert(Intrinsic::NoAliasIdentifyPArg == + Intrinsic::ProvenanceNoAliasIdentifyPArg, + "those must be identical"); + + if (MatchesOp0 || MatchesOpP) { + auto HI = + Handled.insert(I2Deps::value_type(U, {nullptr, nullptr})); + if (HI.second) + out_CreationList.push_back(U); + if (MatchesOp0) { + HI.first->second[0] = I4SC; + } + if (MatchesOpP) { + HI.first->second[1] = I4SC; + } + } + continue; + } + case Intrinsic::noalias_arg_guard: { + // ignore - should be handled by the outer loop ! + continue; + } + + default: + break; + } + // if we get here, we need to inject guards for certain arguments. + // Track which arguments will need one. + auto HI = Handled.insert(I2Deps::value_type(U, {})); + if (HI.second) { + HI.first->second.resize(U->getNumOperands(), nullptr); + if (U->getNumOperands()) { + out_CreationList.push_back(U); + } + } + updateMatchingOperands(U, I, HI.first->second, I4SC); + if (I == CS->getReturnedArgOperand()) { + // also see through call - this does not omit the need of + // introducing a noalias_arg_guard + WorkList.push_back(U); + } + } else { + // ======================================== other -> {} + // this is the generic case... not sure if we should have a elaborate + // check for 'all other instructions'. just acknowledge that we saw it + // and propagate to any users + // - NOTE: if we happen have already handled it, this might indicate + // something interesting that we should handle separately + + bool OnlyGuard = false; + switch (U->getOpcode()) { + case Instruction::GetElementPtr: + case Instruction::BitCast: + case Instruction::AddrSpaceCast: + // Propagate + OnlyGuard = false; + break; + case Instruction::ICmp: + // restrict pointer used in comparison - do not propagate + // provenance + continue; + case Instruction::AtomicRMW: + case Instruction::AtomicCmpXchg: + // NOTE: every instruction handled here should also be handled in + // Phase 3 of ::doit (normally the last 'else' case) + OnlyGuard = true; + break; + default: +#ifndef NDEBUG + llvm::dbgs() << "ERROR: unhandled case:"; + U->dump(); +#endif + assert(false && "unhandled opcode"); + continue; + } + + if (OnlyGuard) { + auto HI = Handled.insert(I2Deps::value_type(U, {})); + if (HI.second) { + // if we get here, we need to inject guards for certain arguments. + // Track which arguments will need one. + HI.first->second.resize(U->getNumOperands(), nullptr); + if (U->getNumOperands()) { + out_CreationList.push_back(U); + } + } + updateMatchingOperands(U, I, HI.first->second, I4SC); + + // Do not propagate + continue; + } + + auto HI = Handled.insert(I2Deps::value_type(U, {})); + // No need to add to out_CreationList + if (!HI.second) { + llvm::errs() + << "WARNING: found an instruction that was already handled:" + << *U << "\n"; + assert(!HI.second && + "We should not encounter a handled instruction ??"); + } + + if (HI.second) { + WorkList.push_back(U); + } + } + } + } + } +} + +typedef SmallDenseMap, Value *, 16> + ValueType2CastMap; +static Value *createBitOrPointerOrAddrSpaceCast(Value *V, Type *T, + ValueType2CastMap &VT2C) { + if (V->getType() == T) + return V; + + // Make sure we remember what casts we introduced + Value *&Entry = VT2C[std::make_pair(V, T)]; + if (Entry == nullptr) { + Instruction *InsertionPoint = cast(V); + if (auto *PHI = dyn_cast(V)) { + InsertionPoint = PHI->getParent()->getFirstNonPHI(); + } else { + InsertionPoint = InsertionPoint->getNextNode(); + } + + IRBuilder<> Builder(InsertionPoint); + Entry = Builder.CreatePointerBitCastOrAddrSpaceCast(V, T); + } + return Entry; +} + +static bool isValidProvenanceNoAliasInsertionPlace(IntrinsicInst *SNA, + Value *InsertionPointV, + DominatorTree &DT) { + assert(SNA->getIntrinsicID() == Intrinsic::provenance_noalias && + "Expect a provenance.noalias"); + Instruction *InsertionPointI = dyn_cast(InsertionPointV); + if (InsertionPointI == nullptr) + return false; + + auto isDominatingOn = [&](Value *Arg) { + auto *ArgI = dyn_cast(Arg); + if (ArgI == nullptr) + return true; + return DT.dominates(ArgI, InsertionPointI); + }; + + for (auto Op : {Intrinsic::ProvenanceNoAliasNoAliasDeclArg, + Intrinsic::ProvenanceNoAliasIdentifyPArg, + Intrinsic::ProvenanceNoAliasIdentifyPProvenanceArg, + Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg, + Intrinsic::ProvenanceNoAliasScopeArg}) { + if (!isDominatingOn(SNA->getOperand(Op))) + return false; + } + + return true; +} + +// combine llvm.provenance.noalias intrinsics as much as possible +void collapseProvenanceNoAlias( + ProvenanceWorklist &CollapseableProvenanceNoAliasIntrinsics, + DominatorTree &DT) { + if (CollapseableProvenanceNoAliasIntrinsics.empty()) + return; + + if (!CollapseableProvenanceNoAliasIntrinsics.empty()) { + // sweep from back to front, then from front to back etc... until no + // modifications are done + do { + LLVM_DEBUG(llvm::dbgs() + << "- Trying to collapse llvm.provenance.noalias\n"); + ProvenanceWorklist NextList; + bool Changed = false; + + // 1) provenance.noaliasA (provenance.noaliasB (....), ...) -> + // provenance.noaliasB(...) + while (!CollapseableProvenanceNoAliasIntrinsics.empty()) { + IntrinsicInst *I = + cast(CollapseableProvenanceNoAliasIntrinsics.back()); + assert(I->getIntrinsicID() == Intrinsic::provenance_noalias); + + CollapseableProvenanceNoAliasIntrinsics.pop_back(); + + // provenance.noalias (provenance.noalias(....), .... ) -> + // provenance.noalias(....) + if (IntrinsicInst *DepI = dyn_cast(I->getOperand(0))) { + // Check if the depending intrinsic is compatible) + if (DepI->getIntrinsicID() == Intrinsic::provenance_noalias && + areProvenanceNoAliasCompatible(DepI, I)) { + // similar enough - look through + LLVM_DEBUG(llvm::dbgs() << "-- Collapsing(1):" << *I << "\n"); + I->replaceAllUsesWith(DepI); + I->eraseFromParent(); + Changed = true; + continue; + } + } + + if (PHINode *DepI = dyn_cast(I->getOperand(0))) { + //@ FIXME: TODO: make more general ? + // provenance.noalias(PHI (fum, self)) -> PHI(provenance.noalias(fum), + // phi self ref) + // - NOTE: only handle the 'simple' case for now ! At least that will + // be correct. + if ((DepI->getNumIncomingValues() == 2) && + (DepI->getNumUses() == 1)) { + LLVM_DEBUG(llvm::dbgs() + << "--- Investigating interesting PHI depenceny\n"); + bool SelfDep0 = (DepI->getOperand(0) == I); + bool SelfDep1 = (DepI->getOperand(1) == I); + if (SelfDep0 || SelfDep1) { + LLVM_DEBUG(llvm::dbgs() << "---- has self dependency\n"); + unsigned ChannelToFollow = SelfDep0 ? 1 : 0; + // Try to find a possible insertion point + if (isValidProvenanceNoAliasInsertionPlace( + I, DepI->getOperand(ChannelToFollow), DT)) { + // create a new provenance.noalias at the insertion point + // FIXME: if DepDepI is not an instruction, we could take the + // end of the BB as insertion location ?? + LLVM_DEBUG(llvm::dbgs() << "----- Migrating !\n"); + Instruction *DepDepI = + cast(DepI->getOperand(ChannelToFollow)); + auto DepDepIIt = DepDepI->getIterator(); + if (isa(DepDepI)) { + DepDepIIt = DepDepI->getParent()->getFirstInsertionPt(); + } else { + ++DepDepIIt; + } + IRBuilder<> builder(DepDepI->getParent(), DepDepIIt); + + auto *NewSNA = builder.CreateProvenanceNoAliasPlain( + DepDepI, + I->getOperand(Intrinsic::ProvenanceNoAliasNoAliasDeclArg), + I->getOperand(Intrinsic::ProvenanceNoAliasIdentifyPArg), + I->getOperand( + Intrinsic::ProvenanceNoAliasIdentifyPProvenanceArg), + I->getOperand( + Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg), + I->getOperand(Intrinsic::ProvenanceNoAliasScopeArg)); + NewSNA->setAAMetadata(I->getAAMetadata()); + I->replaceAllUsesWith(NewSNA); + I->eraseFromParent(); + Changed = true; + // And handle the new provenance.noalias for the next sweep + NextList.push_back(NewSNA); + continue; + } + } + } + } + + NextList.push_back(I); + } + + // 2) provenance.noaliasA (...), provenance.noaliasB(...) --> + // provenance.noaliasA(...) + { + for (Instruction *I : NextList) { + IntrinsicInst *II = cast(I); + Instruction *DominatingUse = II; + + ProvenanceWorklist similarProvenances; + for (User *U : II->getOperand(0)->users()) { + if (IntrinsicInst *UII = dyn_cast(U)) { + if (UII->getParent() && // still valid - ignore already removed + // instructions + UII->getIntrinsicID() == Intrinsic::provenance_noalias && + areProvenanceNoAliasCompatible(II, UII)) { + similarProvenances.push_back(UII); + if (DT.dominates(UII, DominatingUse)) + DominatingUse = UII; + } + } + } + + for (Instruction *SI : similarProvenances) { + if ((SI != DominatingUse) && DT.dominates(DominatingUse, SI)) { + LLVM_DEBUG(llvm::dbgs() << "-- Collapsing(2):" << *SI << "\n"); + Changed = true; + SI->replaceAllUsesWith(DominatingUse); + SI->removeFromParent(); // do not yet erase ! + assert((std::find(NextList.begin(), NextList.end(), SI) != + NextList.end()) && + "Similar ptr_provenance must be on the NextList"); + } + } + } + + if (!Changed) + break; + + // Now eliminate all removed intrinsics + llvm::erase_if(NextList, [](Instruction *I) { + if (I->getParent()) { + return false; + } else { + I->deleteValue(); + return true; + } + }); + } + + CollapseableProvenanceNoAliasIntrinsics = NextList; + } while (CollapseableProvenanceNoAliasIntrinsics.size() > 1); + } +} + +// Look at users of llvm.provenance.noalias to find PHI nodes that are used for +// pointer provenance +static void +deduceProvenancePHIs(ProvenanceWorklist &ProvenanceNoAliasIntrinsics, + InstructionSet &out_ProvenancePHIs, + InstructionSet &out_NoAliasArgGuard, + BasicBlockSet &DeadBasicBlocks) { + LLVM_DEBUG(llvm::dbgs() << "-- Looking up ptr_provenance PHI nodes\n"); + for (Instruction *SNI : ProvenanceNoAliasIntrinsics) { + ProvenanceWorklist worklist = {SNI}; + while (!worklist.empty()) { + Instruction *worker = worklist.pop_back_val(); + LLVM_DEBUG(llvm::dbgs() << "worker" << *worker << "\n"); + if (DeadBasicBlocks.count(worker->getParent())) + continue; // Degenerated llvm-ir; Skip + for (auto *SNIUser_ : worker->users()) { + Instruction *SNIUser = dyn_cast(SNIUser_); + if (SNIUser == nullptr) + continue; + + if (isa(SNIUser)) { + // Identify as a ptr_provenance PHI + if (out_ProvenancePHIs.insert(cast(SNIUser)).second) { + LLVM_DEBUG(llvm::dbgs() << "--- " << *SNIUser << "\n"); + // and propagate + worklist.push_back(SNIUser); + } + } else if (isa(SNIUser) || isa(SNIUser) || + isa(SNIUser) || + isa(SNIUser)) { + assert(SNIUser != worker && "not in ssa form ?"); + // look through select/bitcast/addressspacecast + worklist.push_back(SNIUser); + } else { + // load/store/provenance.noalias/arg.guard -> stop looking + if (auto *CB = dyn_cast(SNIUser)) { + auto CBIID = CB->getIntrinsicID(); + if (CBIID == Intrinsic::noalias_arg_guard) { + assert(CB->getOperand(1) == worker && + "a noalias.arg.guard provenance should be linked to " + "operand 1"); + out_NoAliasArgGuard.insert(CB); + } else if (CBIID == Intrinsic::provenance_noalias) { + // ok + } else { + LLVM_DEBUG(llvm::dbgs() + << "ERROR: unexpected call/intrinsic depending on " + "llvm.provenance.noalias:" + << *CB << "\n"); + assert(false && + "Unexpected llvm.provenance.noalias dependency (1)"); + } + } else { + if (isa(SNIUser) || isa(SNIUser)) { + // ok + } else { + LLVM_DEBUG(llvm::dbgs() + << "ERROR: unexpected instruction depending on " + "llvm.provenance.noalias:" + << *SNIUser << "\n"); + assert(false && + "Unexpected llvm.provenance.noalias dependency (2)"); + } + } + } + } + } + } +} + +static void RetrieveDeadBasicBlocks(Function &F, + BasicBlockSet &out_DeadBasicBlocks) { + df_iterator_default_set Reachable; + + // Mark all reachable blocks. + for (BasicBlock *BB : depth_first_ext(&F, Reachable)) + (void)BB /* Mark all reachable blocks */; + + for (auto &BB : F) { + if (!Reachable.count(&BB)) { + out_DeadBasicBlocks.insert(&BB); + LLVM_DEBUG(llvm::dbgs() << "- Unreachable BB:" << BB.getName() << "\n"); + } + } + + LLVM_DEBUG(llvm::dbgs() << "- There are " << out_DeadBasicBlocks.size() + << " unreachable BB on a total of " + << F.getBasicBlockList().size() << "\n"); +} + +void removeNoAliasIntrinsicsFromDeadBlocks(BasicBlockSet &DeadBlocks) { + LLVM_DEBUG(llvm::dbgs() << "- removing NoAlias intrinsics from " + << DeadBlocks.size() << " dead blocks\n"); + ProvenanceWorklist ToBeRemoved; + + for (auto *BB : DeadBlocks) { + for (auto &I : *BB) { + if (auto CB = dyn_cast(&I)) { + switch (CB->getIntrinsicID()) { + case Intrinsic::noalias: + case Intrinsic::noalias_decl: + case Intrinsic::provenance_noalias: + case Intrinsic::noalias_arg_guard: + case Intrinsic::noalias_copy_guard: + ToBeRemoved.push_back(&I); + break; + default: + break; + } + } + } + } + + LLVM_DEBUG(llvm::dbgs() << "-- Removing " << ToBeRemoved.size() + << " intrinsics\n"); + for (auto *I : ToBeRemoved) { + I->replaceAllUsesWith(UndefValue::get(I->getType())); + I->eraseFromParent(); + } +} + +bool PropagateAndConvertNoAliasPass::doit(Function &F, DominatorTree &DT) { + LLVM_DEBUG(llvm::dbgs() << "PropagateAndConvertNoAliasPass:\n"); + + // PHASE 0: find interesting instructions + // - Find all: + // -- Propagatable noalias intrinsics + // -- Load instructions + // -- Store instructions + ProvenanceWorklist InstructionsForProvenance; + ProvenanceWorklist LoadStoreIntrinsicInstructions; + ProvenanceWorklist LookThroughIntrinsics; + ProvenanceWorklist CollapseableProvenanceNoAliasIntrinsics; + ValueType2CastMap VT2C; + InstructionSet ProvenancePHIs; + ProvenanceWorklist DegeneratedNoAliasAndNoAliasArgGuards; + ProvenanceWorklist RemainingNoAliasArgGuards; + InstructionSet DecentNoAliasArgGuards; + + // Do not depend on simplifyCFG or eliminateDeadBlocks. Forcing any of them + // before the propagate can result in significant code degradations :( + // Live with the fact that we can observe degenerated llvm-ir. + BasicBlockSet DeadBasicBlocks; + RetrieveDeadBasicBlocks(F, DeadBasicBlocks); + + LLVM_DEBUG(llvm::dbgs() << "- gathering intrinsics, stores, loads:\n"); + for (auto &BB : F) { + if (DeadBasicBlocks.count(&BB)) + continue; // Skip dead basic blocks + + for (auto &I : BB) { + if (auto CB = dyn_cast(&I)) { + auto ID = CB->getIntrinsicID(); + if (ID == Intrinsic::noalias) { + LLVM_DEBUG(llvm::dbgs() << "-- found intrinsic:" << I << "\n"); + auto Op0 = I.getOperand(0); + if (isa(Op0)) { + LLVM_DEBUG(llvm::dbgs() << "--- degenerated\n"); + DegeneratedNoAliasAndNoAliasArgGuards.push_back(&I); + } else { + InstructionsForProvenance.push_back(&I); + LoadStoreIntrinsicInstructions.push_back(&I); + LookThroughIntrinsics.push_back(&I); + } + } else if (ID == Intrinsic::noalias_arg_guard) { + LLVM_DEBUG(llvm::dbgs() << "-- found intrinsic:" << I << "\n"); + auto Op0 = I.getOperand(0); + auto Op1 = I.getOperand(1); + if (isa(Op0) || isa(Op1) || (Op0 == Op1)) { + LLVM_DEBUG(llvm::dbgs() << "--- degenerated\n"); + DegeneratedNoAliasAndNoAliasArgGuards.push_back(&I); + } else { + RemainingNoAliasArgGuards.push_back(&I); + } + } else if (ID == Intrinsic::provenance_noalias) { + CollapseableProvenanceNoAliasIntrinsics.push_back(&I); + } + } else if (auto LI = dyn_cast(&I)) { + LLVM_DEBUG(llvm::dbgs() << "-- found load:" << I << "\n"); + LoadStoreIntrinsicInstructions.push_back(LI); + } else if (auto SI = dyn_cast(&I)) { + LLVM_DEBUG(llvm::dbgs() << "-- found store:" << I << "\n"); + LoadStoreIntrinsicInstructions.push_back(SI); + } + } + } + + // When there are no noalias related intrinsics, don't do anything. + if (LookThroughIntrinsics.empty() && InstructionsForProvenance.empty() && + DegeneratedNoAliasAndNoAliasArgGuards.empty() && + CollapseableProvenanceNoAliasIntrinsics.empty() && + RemainingNoAliasArgGuards.empty()) { + LLVM_DEBUG(llvm::dbgs() << "- Nothing to do\n"); + return false; + } + + if (!DeadBasicBlocks.empty()) { + removeNoAliasIntrinsicsFromDeadBlocks(DeadBasicBlocks); + } + + LLVM_DEBUG( + llvm::dbgs() << "- Looking through degenerated llvm.noalias.arg.guard\n"); + for (Instruction *I : DegeneratedNoAliasAndNoAliasArgGuards) { + I->replaceAllUsesWith(I->getOperand(0)); + I->eraseFromParent(); + } + + LLVM_DEBUG(llvm::dbgs() << "- Retrieving ptr_provenance PHI nodes and decent " + "llvm.noalias.arg.guard\n"); + deduceProvenancePHIs(CollapseableProvenanceNoAliasIntrinsics, ProvenancePHIs, + DecentNoAliasArgGuards, DeadBasicBlocks); + + LLVM_DEBUG( + llvm::dbgs() << "- looking through remaining llvm.noalias.arg.guard"); + for (Instruction *I : RemainingNoAliasArgGuards) { + if (DecentNoAliasArgGuards.find(I) != DecentNoAliasArgGuards.end()) { + InstructionsForProvenance.push_back(I); + LoadStoreIntrinsicInstructions.push_back(I); + LookThroughIntrinsics.push_back(I); + } else { + I->replaceAllUsesWith(I->getOperand(0)); + I->eraseFromParent(); + } + } + + LLVM_DEBUG(llvm::dbgs() << "- Find out what to do:\n"); + + // PHASE 1: forward pass: + // - Start with all intrinsics + // -- Track all users + // -- Interesting users (noalias intrinsics, select, PHI, load/store) + // -- Do this recursively for users that we can look through + I2Deps Handled; // instruction -> { dependencies } + ProvenanceWorklist + CreationList; // Tracks all keys in Handled, but in a reproducable way + propagateInstructionsForProvenance(InstructionsForProvenance, Handled, + CreationList, ProvenancePHIs, + DeadBasicBlocks); + + // PHASE 2: add missing load/store/intrinsic instructions: + for (auto *I : LoadStoreIntrinsicInstructions) { + if (isa(I)) { + if (Handled.insert(I2Deps::value_type(I, {nullptr})).second) + CreationList.push_back(I); + } else { // Store or llvm.no_alias + if (Handled.insert(I2Deps::value_type(I, {nullptr, nullptr})).second) + CreationList.push_back(I); + } + } + +#if !defined(NDEBUG) + auto dumpit = [](I2Deps::value_type &H) { + auto &out = llvm::dbgs(); + out << *H.first << " -> {"; + bool comma = false; + for (auto D : H.second) { + if (comma) + out << ","; + comma = true; + if (D == nullptr) { + out << "nullptr"; + } else { + out << *D; + } + } + out << "}\n"; + }; +#endif + + // PHASE 3: reconstruct alternative tree + // - detected dependencies: replace them by new instructions + // - undetected dependencies: use the original dependency + // NOTE: See explanation in propagateInstructionsForProvenance for more + // information ! + LLVM_DEBUG(llvm::dbgs() << "- Reconstructing tree:\n"); + + ProvenanceWorklist UnresolvedPHI; + SmallDenseMap I2NewV; + SmallDenseMap I2ArgGuard; + + auto getNewIOrOperand = [&](Instruction *DepOp, Value *OrigOp) { + assert(((!DepOp) || I2NewV.count(DepOp)) && "DepOp should be known"); + return DepOp ? static_cast(I2NewV[DepOp]) : OrigOp; + }; + + // Helper lambda for inserting a new noalias.arg.guard + auto setNewNoaliasArgGuard = [&](Instruction *I, unsigned Index, + Instruction *DepOp) { + auto *ProvOp = cast(I2NewV[DepOp]); + // if we get here, the operand has to be an 'Instruction' + // (otherwise, DepOp would not be set). + auto *OpI = cast(I->getOperand(Index)); + auto &ArgGuard = I2ArgGuard[OpI]; + if (ArgGuard == nullptr) { + // create the instruction close to the origin, so that we don't introduce + // bad dependencies + auto InsertionPointIt = OpI->getIterator(); + ++InsertionPointIt; + if (isa(OpI)) { + auto End = OpI->getParent()->end(); + while (InsertionPointIt != End) { + if (!isa(*InsertionPointIt)) + break; + ++InsertionPointIt; + } + } + IRBuilder<> BuilderForArgs(OpI->getParent(), InsertionPointIt); + ArgGuard = BuilderForArgs.CreateNoAliasArgGuard( + OpI, createBitOrPointerOrAddrSpaceCast(ProvOp, OpI->getType(), VT2C), + OpI->getName() + ".guard"); + } + I->setOperand(Index, ArgGuard); + }; + + // Map known provenance.noalias that are not handle to themselves + for (auto SNI : CollapseableProvenanceNoAliasIntrinsics) + if (Handled.find(SNI) == Handled.end()) + I2NewV[SNI] = SNI; + + // We are doing a number of sweeps. This should always end. Normally the + // amount of sweeps is low. During initial development, a number of bugs where + // found by putting a hard limit on the the amount. + unsigned Watchdog = 1000000; // Only used in assertions build + (void)Watchdog; + for (auto CloneableInst : CreationList) { + assert(Handled.count(CloneableInst) && + "Entries in CreationList must also be in Handled"); + assert(!Handled[CloneableInst].empty() && + "Only non-empty items should be added to the CreationList"); + + LLVM_DEBUG(llvm::dbgs() << "- "; dumpit(*Handled.find(CloneableInst))); + ProvenanceWorklist Worklist = {CloneableInst}; + + while (!Worklist.empty()) { + Instruction *I = Worklist.back(); + + if (I2NewV.count(I)) { + // already exists - skip + Worklist.pop_back(); + continue; + } + + LLVM_DEBUG(llvm::dbgs() << "-- Reconstructing:" << *I << "\n"); + + // Check if we have all the needed arguments + auto HandledIt = Handled.find(I); + if (HandledIt == Handled.end()) { + // This can happen after propagation of a llvm.noalias.arg.guard + Worklist.pop_back(); + I2NewV[I] = I; + LLVM_DEBUG(llvm::dbgs() << "--- Connected to an existing path!\n"); + continue; + } + + // If we are a PHI node, just create it + if (isa(I)) { + if (ProvenancePHIs.count(cast(I)) == 0) { + // But only if it is _not_ a ptr_provenance PHI node + // ======================================== PHI -> { ..... } + IRBuilder<> Builder(I); + I2NewV[I] = Builder.CreatePHI(I->getType(), I->getNumOperands(), + Twine("prov.") + I->getName()); + + UnresolvedPHI.push_back(I); + } else { + I2NewV[I] = I; // Map already existing Provenance PHI to itself + } + Worklist.pop_back(); + continue; + } + + LLVM_DEBUG(llvm::dbgs() << "--- "; dumpit(*HandledIt)); + auto &Deps = HandledIt->second; + assert((!Deps.empty()) && + "Any creatable instruction must have some dependent operands"); + bool canCreateInstruction = true; + for (auto *DepOp : Deps) { + if (DepOp != nullptr) { + if (I2NewV.count(DepOp) == 0) { + canCreateInstruction = false; + Worklist.push_back(DepOp); + } + } + } +#if !defined(NDEBUG) + if (--Watchdog == 0) { + llvm::errs() + << "PropagateAndConvertNoAlias: ERROR: WATCHDOG TRIGGERED !\n"; + assert(false && "PropagateAndConvertNoAlias: WATCHDOG TRIGGERED"); + } +#endif + if (canCreateInstruction) { + Worklist.pop_back(); + IRBuilder<> Builder(I); + + if (isa(I)) { + // ======================================== select -> { lhs, rhs } + I2NewV[I] = Builder.CreateSelect( + I->getOperand(0), + createBitOrPointerOrAddrSpaceCast( + getNewIOrOperand(Deps[0], I->getOperand(1)), I->getType(), + VT2C), + createBitOrPointerOrAddrSpaceCast( + getNewIOrOperand(Deps[1], I->getOperand(2)), I->getType(), + VT2C), + Twine("prov.") + I->getName()); + } else if (isa(I)) { + // ======================================== load -> { ptr } + LoadInst *LI = cast(I); + + if (Deps[0]) { + if (!LI->hasNoaliasProvenanceOperand() || + isa(LI->getNoaliasProvenanceOperand()) || + (LI->getPointerOperand() == + LI->getNoaliasProvenanceOperand())) { + LI->setNoaliasProvenanceOperand(createBitOrPointerOrAddrSpaceCast( + I2NewV[Deps[0]], LI->getPointerOperandType(), VT2C)); + } else { + // nothing to do - propagation should have happend through the + // provenance ! + // TODO: we might want to add an extra check that the load + // ptr_provenance was updated + } + } else { + // No extra dependency -> do nothing + // Note: originally we were adding a 'UndefValue' if there was no + // ptr_provenance. But that has the same effect as doing nothing. + } + I2NewV[I] = I; + } else if (isa(I)) { + // ======================================== store -> { val, ptr } + StoreInst *SI = cast(I); + + if (Deps[0]) { + // We try to store a restrict pointer - restrictness + Instruction *DepOp = Deps[0]; + setNewNoaliasArgGuard(I, 0, DepOp); + } + if (Deps[1]) { + if (!SI->hasNoaliasProvenanceOperand() || + isa(SI->getNoaliasProvenanceOperand()) || + (SI->getPointerOperand() == + SI->getNoaliasProvenanceOperand())) { + SI->setNoaliasProvenanceOperand(createBitOrPointerOrAddrSpaceCast( + I2NewV[Deps[1]], SI->getPointerOperandType(), VT2C)); + } else { + // nothing to do - propagation should have happend through the + // provenance ! + // TODO: we might want to add an extra check that the store + // ptr_provenance was updated + } + } else { + // No extra dependency -> do nothing + // Note: originally we were adding a 'UndefValue' if there was no + // ptr_provenance. But that has the same effect as doing nothing. + } + I2NewV[I] = I; + } else if (isa(I)) { + // We try to insert a restrict pointer into a struct - track it. + // Track generated noalias_arg_guard also in I2NewI + assert(Deps.size() == 1 && + "InsertValue tracks exactly one dependency"); + Instruction *DepOp = Deps[0]; + setNewNoaliasArgGuard(I, 1, DepOp); + } else if (isa(I)) { + // We try to convert a restrict pointer to an integer - track it s + // SROA can produce this. + // Track generated noalias_arg_guard also in I2NewI + assert(Deps.size() == 1 && + "InsertValue tracks exactly one dependency"); + Instruction *DepOp = Deps[0]; + setNewNoaliasArgGuard(I, 0, DepOp); + } else { + // =============================== ret -> { ...... } + // =============================== call/invoke/intrinsic -> { ...... } + auto CB = dyn_cast(I); + if (CB) { + assert(CB && "If we get here, we should have a Call"); + switch (CB->getIntrinsicID()) { + case Intrinsic::noalias: { + // convert + assert(Deps.size() == 2); + Value *IdentifyPProvenance; + if (Deps[1]) { + // do the same as with the ptr_provenance in the load + // instruction + IdentifyPProvenance = createBitOrPointerOrAddrSpaceCast( + I2NewV[Deps[1]], + I->getOperand(Intrinsic::NoAliasIdentifyPArg)->getType(), + VT2C); + } else { + IdentifyPProvenance = UndefValue::get( + I->getOperand(Intrinsic::NoAliasIdentifyPArg)->getType()); + } + Instruction *NewI = Builder.CreateProvenanceNoAliasPlain( + getNewIOrOperand(Deps[0], I->getOperand(0)), + I->getOperand(Intrinsic::NoAliasNoAliasDeclArg), + I->getOperand(Intrinsic::NoAliasIdentifyPArg), + IdentifyPProvenance, + I->getOperand(Intrinsic::NoAliasIdentifyPObjIdArg), + I->getOperand(Intrinsic::NoAliasScopeArg)); + I2NewV[I] = NewI; + CollapseableProvenanceNoAliasIntrinsics.push_back(NewI); + + // Copy over metadata that is related to the 'getOperand(1)' (aka + // P) + NewI->setAAMetadata(I->getAAMetadata()); + continue; + } + case Intrinsic::noalias_arg_guard: { + // no update needed - depending llvm.provenance.noalias/gep must + // have been updated + continue; + } + case Intrinsic::provenance_noalias: { + // update + assert((Deps[0] || Deps[1]) && + "provenance.noalias update needs a depending operand"); + if (Deps[0]) + I->setOperand(0, createBitOrPointerOrAddrSpaceCast( + I2NewV[Deps[0]], I->getType(), VT2C)); + if (Deps[1]) + I->setOperand( + Intrinsic::ProvenanceNoAliasIdentifyPProvenanceArg, + createBitOrPointerOrAddrSpaceCast( + I2NewV[Deps[1]], + I->getOperand(Intrinsic::ProvenanceNoAliasIdentifyPArg) + ->getType(), + VT2C)); + I2NewV[I] = I; + continue; + } + default: + break; + } + } else { + assert(isa(I) || + isa(I) || + isa(I)); + } + + // Introduce a noalias_arg_guard for every argument that is + // annotated + assert(I->getNumOperands() == Deps.size()); + for (unsigned i = 0, ci = I->getNumOperands(); i < ci; ++i) { + Instruction *DepOp = Deps[i]; + if (DepOp) { + setNewNoaliasArgGuard(I, i, DepOp); + } + } + I2NewV[I] = I; + } + } + } + } + + // Phase 4: resolve the generated PHI nodes + LLVM_DEBUG(llvm::dbgs() << "- Resolving " << UnresolvedPHI.size() + << " PHI nodes\n"); + for (auto *PHI_ : ProvenancePHIs) { + PHINode *PHI = cast(PHI_); + auto it = Handled.find(PHI); + if (it != Handled.end()) { + LLVM_DEBUG(llvm::dbgs() << "-- Orig PHI:" << *PHI << "\n"); + auto &Deps = it->second; + for (unsigned i = 0, ci = Deps.size(); i < ci; ++i) { + LLVM_DEBUG(if (Deps[i]) llvm::dbgs() + << "--- UPDATING:Deps:" << *Deps[i] << "\n"); + Value *IncomingValue = Deps[i] ? I2NewV[Deps[i]] : nullptr; + if (IncomingValue) { + if (IncomingValue->getType() != PHI->getType()) { + IncomingValue = createBitOrPointerOrAddrSpaceCast( + IncomingValue, PHI->getType(), VT2C); + } + LLVM_DEBUG(llvm::dbgs() + << "--- IncomingValue:" << *IncomingValue << "\n"); + PHI->setIncomingValue(i, IncomingValue); + } + } + LLVM_DEBUG(llvm::dbgs() << "-- Adapted PHI:" << *PHI << "\n"); + } + } + + for (auto &PHI : UnresolvedPHI) { + PHINode *BasePHI = cast(PHI); + PHINode *NewPHI = cast(I2NewV[PHI]); + auto &Deps = Handled[PHI]; + + LLVM_DEBUG(llvm::dbgs() << "-- Orig PHI:" << *BasePHI << "\n"); + LLVM_DEBUG(llvm::dbgs() << "-- New PHI:" << *NewPHI << "\n"); + LLVM_DEBUG(llvm::dbgs() << "-- Deps: " << Deps.size() << "\n"); + for (unsigned i = 0, ci = BasePHI->getNumOperands(); i < ci; ++i) { + auto *BB = BasePHI->getIncomingBlock(i); + Value *IncomingValue = + Deps[i] ? I2NewV[Deps[i]] : BasePHI->getIncomingValue(i); + if (IncomingValue == nullptr) { + LLVM_DEBUG(llvm::dbgs() + << "--- hmm.. operand " << i << " became undef\n"); + IncomingValue = UndefValue::get(NewPHI->getType()); + } + if (IncomingValue->getType() != NewPHI->getType()) { + IncomingValue = createBitOrPointerOrAddrSpaceCast( + IncomingValue, NewPHI->getType(), VT2C); + } + NewPHI->addIncoming(IncomingValue, BB); + } + } + + // Phase 5: Removing the llvm.noalias + LLVM_DEBUG(llvm::dbgs() << "- Looking through intrinsics:\n"); + for (Instruction *I : LookThroughIntrinsics) { + auto CB = dyn_cast(I); + if (CB->getIntrinsicID() == Intrinsic::noalias || + CB->getIntrinsicID() == Intrinsic::noalias_arg_guard) { + LLVM_DEBUG(llvm::dbgs() << "-- Eliminating: " << *I << "\n"); + I->replaceAllUsesWith(I->getOperand(0)); + I->eraseFromParent(); + } else { + llvm_unreachable("unhandled lookthrough intrinsic"); + } + } + + // Phase 6: Collapse llvm.provenance.noalias where possible... + // - hmm: should we do this as a complete separate pass ?? + collapseProvenanceNoAlias(CollapseableProvenanceNoAliasIntrinsics, DT); + + return true; +} + +} // namespace llvm Index: llvm/lib/Transforms/Scalar/SROA.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SROA.cpp +++ llvm/lib/Transforms/Scalar/SROA.cpp @@ -62,6 +62,7 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/MDBuilder.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" @@ -117,6 +118,14 @@ namespace { +static llvm::IntrinsicInst *getBaseAsCopyGuardOrNull(llvm::Value *V) { + llvm::IntrinsicInst *II = dyn_cast(V->stripInBoundsOffsets()); + if (II && (II->getIntrinsicID() == Intrinsic::noalias_copy_guard)) + return II; + + return nullptr; +} + /// A custom IRBuilder inserter which prefixes all names, but only in /// Assert builds. class IRBuilderPrefixedInserter final : public IRBuilderDefaultInserter { @@ -634,6 +643,98 @@ return foldSelectInst(cast(I)); } +class MatchOffset { + uint64_t TargetOffset; + bool WasMatched = false; + +public: + MatchOffset(uint64_t TargetOffset) : TargetOffset(TargetOffset) {} + + bool isOffsetTooLarge(uint64_t Offset) const { + return WasMatched || (Offset > TargetOffset); + } + + void track(uint64_t Offset, uint64_t /*Size*/) { + if (TargetOffset == Offset) + WasMatched = true; + } + +public: + bool wasMatched() const { return WasMatched; } +}; + +class GatherRestrictPointers { + uint64_t SliceStart; + uint64_t SliceEnd; + SmallVectorImpl> &PtrOffsetSizes; + +public: + GatherRestrictPointers(uint64_t SliceStart, uint64_t SliceEnd, + SmallVectorImpl> &C) + : SliceStart(SliceStart), SliceEnd(SliceEnd), PtrOffsetSizes(C) {} + + bool isOffsetTooLarge(uint64_t Offset) const { return (Offset >= SliceEnd); } + + void track(uint64_t Offset, uint64_t Size) { + if ((SliceStart <= Offset) && (Offset + Size) <= SliceEnd) + PtrOffsetSizes.push_back(std::make_pair(Offset - SliceStart, Size)); + } +}; + +// Returns the 'GlobalSize' of the item under investigation +template +uint64_t gatherValidNoAliasPointerOffsets(T &Handler, + const MDNode *NoAliasOffsets, + uint64_t BaseOffset = 0) { + MDBuilder::NoAliasOffsetsNode NAO(NoAliasOffsets); + // Input: { GlobalSize, [offset, (ptrsize | !struct), count]+ } + + uint64_t GlobalSize = NAO.getGlobalSize(); + + unsigned NumFields = NAO.getNumEntries(); + for (unsigned Index = 0; Index < NumFields; ++Index) { + if (Handler.isOffsetTooLarge(BaseOffset)) + break; + + auto F = NAO.getField(Index); + uint64_t LocalOffset = BaseOffset + F.Offset; + uint64_t LocalCount = F.Count; + // Note: a LocalCount of 0 will be bounded by the AllocSize + if (!F.Record) { + uint64_t LocalSize = F.Size; + assert(LocalSize > 0 && "We cannot handle a pointer size of 0"); + + uint64_t I = 0; + do { + if (Handler.isOffsetTooLarge(LocalOffset)) + break; + + Handler.track(LocalOffset, LocalSize); + + I++; + LocalOffset += LocalSize; + } while (LocalCount != I); + } else { + uint64_t I = 0; + do { + if (Handler.isOffsetTooLarge(LocalOffset)) + break; + + uint64_t LocalSize = + gatherValidNoAliasPointerOffsets(Handler, F.Record, LocalOffset); + assert(((LocalCount != 0) || (LocalSize > 0)) && + "We cannot handle a struct with empty size"); + if (LocalSize == 0) + break; + LocalOffset += LocalSize; + I++; + } while (LocalCount != I); + } + } + + return GlobalSize; +} + /// Builder for the alloca slices. /// /// This class builds a set of alloca slices by recursively visiting the uses @@ -653,12 +754,25 @@ /// Set to de-duplicate dead instructions found in the use walk. SmallPtrSet VisitedDeadInsts; + // llvm.noalias.copy.guard, offset + SmallVector, 4> PendingNoAliasCopyGuards; + public: SliceBuilder(const DataLayout &DL, AllocaInst &AI, AllocaSlices &AS) : PtrUseVisitor(DL), AllocSize(DL.getTypeAllocSize(AI.getAllocatedType()).getFixedSize()), AS(AS) {} + PtrInfo visitPtrAndNoAliasCopyGuards(Instruction &I) { + PtrInfo PI = visitPtr(I); + if (!PI.isAborted()) { + for (auto &CGAndOffset : PendingNoAliasCopyGuards) + visitPendingNoAliasCopyGuard(*CGAndOffset.first, CGAndOffset.second); + } + + return PI; + } + private: void markAsDead(Instruction &I) { if (VisitedDeadInsts.insert(&I).second) @@ -778,6 +892,13 @@ assert((!LI.isSimple() || LI.getType()->isSingleValueType()) && "All simple FCA loads should have been pre-split"); + if (U->getOperandNo() == LI.getNoaliasProvenanceOperandIndex()) { + // Skip provenance + assert(LI.hasNoaliasProvenanceOperand() && + LI.getNoaliasProvenanceOperand() == *U); + return; + } + if (!IsOffsetKnown) return PI.setAborted(&LI); @@ -793,6 +914,13 @@ } void visitStoreInst(StoreInst &SI) { + if (U->getOperandNo() == SI.getNoaliasProvenanceOperandIndex()) { + // Skip provenance + assert(SI.hasNoaliasProvenanceOperand() && + SI.getNoaliasProvenanceOperand() == *U); + return; + } + Value *ValOp = SI.getValueOperand(); if (ValOp == *U) return PI.setEscapedAndAborted(&SI); @@ -827,6 +955,14 @@ assert((!SI.isSimple() || ValOp->getType()->isSingleValueType()) && "All simple FCA stores should have been pre-split"); handleLoadOrStore(ValOp->getType(), SI, Offset, Size, SI.isVolatile()); + + if (auto *LI = dyn_cast(SI.getValueOperand())) { + // When we get here, the Store is based on an AllocaInst. + // Make sure to track any source dependencies on a llvm.noalias.copy.guard + // when the source was not based on the AllocaInst. + rememberIfBasedOnNoAliasCopyGuard(LI->getPointerOperand(), + Offset.getZExtValue()); + } } void visitMemSetInst(MemSetInst &II) { @@ -925,6 +1061,64 @@ // Check that we ended up with a valid index in the map. assert(AS.Slices[PrevIdx].getUse()->getUser() == &II && "Map index doesn't point back to a slice with this user."); + + // When we get here, one of the operands is based on an AllocaInst. + // Make sure to track any source dependencies on a llvm.noalias.copy.guard + // when the source was not based on the AllocaInst. + rememberIfBasedOnNoAliasCopyGuard(II.getSource(), Offset.getZExtValue()); + } + + void rememberIfBasedOnNoAliasCopyGuard(Value *V, uint64_t TheOffset) { + if (auto II = getBaseAsCopyGuardOrNull(V)) { + for (auto CGOff : PendingNoAliasCopyGuards) { + if (CGOff.first == II && CGOff.second == TheOffset) + return; + } + + PendingNoAliasCopyGuards.emplace_back(II, TheOffset); + } + } + + void visitNoAliasCopyGuard(IntrinsicInst &II) { + assert(II.getIntrinsicID() == Intrinsic::noalias_copy_guard && + "We need a llvm.noalias.copy.guard here"); + rememberIfBasedOnNoAliasCopyGuard(&II, Offset.getZExtValue()); + enqueueUsers(II); + } + + void visitPendingNoAliasCopyGuard(IntrinsicInst &II, uint64_t BaseOffset) { + LLVM_DEBUG( + llvm::dbgs() + << "AllocaSlices::SliceBuilder: handling llvm.noalias.copy.guard:" << II + << ":@" << BaseOffset << ":" << AllocSize << "\n"); + // Identify the usage, so that it can be split + if (II.use_empty()) + return markAsDead(II); + + SmallVector, 4> PtrOffsetSizes; + + // Provide as many slices as we have restrict pointers + MDNode *CopyGuardIndices = + cast(cast( + II.getOperand(Intrinsic::NoAliasCopyGuardIndicesArg)) + ->getMetadata()); + auto Tracker = + GatherRestrictPointers(BaseOffset, AllocSize, PtrOffsetSizes); + gatherValidNoAliasPointerOffsets(Tracker, CopyGuardIndices); + LLVM_DEBUG(llvm::dbgs() << "noalias pointers are at:\n"; + for (auto &P + : PtrOffsetSizes) { + llvm::dbgs() + << " - [" << P.first << "," << P.first + P.second << ")\n"; + }); + + U = &II.getOperandUse(0); + unsigned AS = II.getOperand(0)->getType()->getPointerAddressSpace(); + APInt TheBaseOffset(DL.getIndexSizeInBits(AS), BaseOffset); + for (auto &P : PtrOffsetSizes) { + APInt TheOffset = TheBaseOffset + P.first; + insertUse(II, TheOffset, P.second, false); + } } // Disable SRoA for any intrinsics except for lifetime invariants and @@ -947,6 +1141,52 @@ insertUse(II, Offset, Size, true); return; } + // look through noalias intrinsics + if (II.getIntrinsicID() == Intrinsic::noalias_decl) { + insertUse(II, Offset, AllocSize, true); + // do not enqueue direct users (?) They should be handled through a + // dependency on the original alloca + return; + } + if (II.getIntrinsicID() == Intrinsic::noalias) { + if (U->getOperandNo() == Intrinsic::NoAliasIdentifyPArg) { + insertUse(II, Offset, + DL.getTypeStoreSize( + II.getOperand(Intrinsic::NoAliasIdentifyPArg)->getType()), + false); + return; + } + if (U->getOperandNo() == 0) { + assert(II.getOperand(0) == *U); + // _only_ look through the first argument + enqueueUsers(II); + } + return; + } + if (II.getIntrinsicID() == Intrinsic::provenance_noalias) { + if (U->getOperandNo() == Intrinsic::ProvenanceNoAliasIdentifyPArg) { + insertUse(II, Offset, + DL.getTypeStoreSize( + II.getOperand(Intrinsic::ProvenanceNoAliasIdentifyPArg) + ->getType()), + false); + return; + } + // hmmm - do not look through the first argument for a + // llvm.provenance.noalias + return; + } + if (II.getIntrinsicID() == Intrinsic::noalias_arg_guard) { + if (U->getOperandNo() == 0) { + // _only_ look through the first argument + enqueueUsers(II); + } + return; + } + if (II.getIntrinsicID() == Intrinsic::noalias_copy_guard) { + visitNoAliasCopyGuard(II); + return; + } if (II.isLaunderOrStripInvariantGroup()) { enqueueUsers(II); @@ -1069,7 +1309,7 @@ #endif PointerEscapingInstr(nullptr) { SliceBuilder PB(DL, AI, *this); - SliceBuilder::PtrInfo PtrI = PB.visitPtr(AI); + SliceBuilder::PtrInfo PtrI = PB.visitPtrAndNoAliasCopyGuards(AI); if (PtrI.isEscaped() || PtrI.isAborted()) { // FIXME: We should sink the escape vs. abort info into the caller nicely, // possibly by just storing the PtrInfo in the AllocaSlices. @@ -1127,6 +1367,18 @@ #endif // !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +static IntrinsicInst *partitionRepresentsNoAliasPointer(Partition &P) { + // A partition that has a 'llvm.noalias.copy.guard' use, represents a + // noalias pointer + for (auto &I : P) { + Use *U = I.getUse(); + if (auto *II = dyn_cast(U->getUser())) + if (II->getIntrinsicID() == Intrinsic::noalias_copy_guard) + return II; + } + return nullptr; +} + /// Walk the range of a partitioning looking for a common type to cover this /// sequence of slices. static std::pair @@ -1268,7 +1520,14 @@ LLVM_DEBUG(dbgs() << " original: " << PN << "\n"); LoadInst *SomeLoad = cast(PN.user_back()); - Type *LoadTy = SomeLoad->getType(); + if (SomeLoad->getPointerOperand() != &PN) { + // this must be the provenance -> ignore the speculation for now + LLVM_DEBUG(llvm::dbgs() << " not speculating dependency on provenance: " + << *SomeLoad << "\n"); + return; + } + + Type *LoadTy = cast(PN.getType())->getElementType(); IRBuilderTy PHIBuilder(&PN); PHINode *NewPN = PHIBuilder.CreatePHI(LoadTy, PN.getNumIncomingValues(), PN.getName() + ".sroa.speculated"); @@ -2247,6 +2506,9 @@ const uint64_t NewAllocaBeginOffset, NewAllocaEndOffset; Type *NewAllocaTy; + IntrinsicInst *OldNoAliasDecl = nullptr; + IntrinsicInst *NewNoAliasDecl = nullptr; + // This is a convenience and flag variable that will be null unless the new // alloca's integer operations should be widened to this integer type due to // passing isIntegerWideningViable above. If it is non-null, the desired @@ -2278,6 +2540,7 @@ uint64_t SliceSize = 0; bool IsSplittable = false; bool IsSplit = false; + bool RepresentsNoAlias = false; Use *OldUse = nullptr; Instruction *OldPtr = nullptr; @@ -2296,7 +2559,8 @@ uint64_t NewAllocaEndOffset, bool IsIntegerPromotable, VectorType *PromotableVecTy, SmallSetVector &PHIUsers, - SmallSetVector &SelectUsers) + SmallSetVector &SelectUsers, + bool ReprNoAlias) : DL(DL), AS(AS), Pass(Pass), OldAI(OldAI), NewAI(NewAI), NewAllocaBeginOffset(NewAllocaBeginOffset), NewAllocaEndOffset(NewAllocaEndOffset), @@ -2311,14 +2575,15 @@ ElementTy(VecTy ? VecTy->getElementType() : nullptr), ElementSize(VecTy ? DL.getTypeSizeInBits(ElementTy).getFixedSize() / 8 : 0), - PHIUsers(PHIUsers), SelectUsers(SelectUsers), - IRB(NewAI.getContext(), ConstantFolder()) { + RepresentsNoAlias(ReprNoAlias), PHIUsers(PHIUsers), + SelectUsers(SelectUsers), IRB(NewAI.getContext(), ConstantFolder()) { if (VecTy) { assert((DL.getTypeSizeInBits(ElementTy).getFixedSize() % 8) == 0 && "Only multiple-of-8 sized vector elements are viable"); ++NumVectorized; } assert((!IntTy && !VecTy) || (IntTy && !VecTy) || (!IntTy && VecTy)); + prepareNoAliasDecl(); } bool visit(AllocaSlices::const_iterator I) { @@ -2341,7 +2606,7 @@ SliceSize = NewEndOffset - NewBeginOffset; OldUse = I->getUse(); - OldPtr = cast(OldUse->get()); + OldPtr = dyn_cast(OldUse->get()); Instruction *OldUserI = cast(OldUse->getUser()); IRB.SetInsertPoint(OldUserI); @@ -2865,6 +3130,84 @@ return !II.isVolatile(); } + Instruction *detachFromNoAliasCopyGuard(Instruction *DepPtr, + Instruction *NACG) { + assert(getBaseAsCopyGuardOrNull(DepPtr) == NACG && + "DepPtr must depend on NACG"); + + // Follow first arg until we hit the llvm.noalias.copy.guard + Instruction *Ptr = cast(DepPtr); + while (true) { + if (Ptr->getNumUses() != 1) + break; + Instruction *ParentPtr = cast(Ptr->getOperand(0)); + if (ParentPtr == NACG) { + // we got here with only single uses - just remove the dependency + Ptr->setOperand(0, NACG->getOperand(0)); + return DepPtr; + } + Ptr = ParentPtr; + } + + assert(false && "Multiple use found - we should duplicate the chain"); + return DepPtr; + } + + Instruction *maybeIntroduceNoAlias(LoadInst *Load, Value *PtrOperand) { + if (!RepresentsNoAlias) + return Load; + + auto NACG = getBaseAsCopyGuardOrNull(PtrOperand); + if (NACG == nullptr) { + // strange, but could happen + LLVM_DEBUG(llvm::dbgs() + << "maybeIntroduceNoAlias: RepresentsNoAlias is true," + "but no copy.guard seen\n"); + return Load; + } + + Value *NoAliasDecl = + NACG->getOperand(Intrinsic::NoAliasCopyGuardNoAliasDeclArg); + + auto ScopeArg = NACG->getOperand(Intrinsic::NoAliasCopyGuardScopeArg); + + auto NewDepPtr = Load->getPointerOperand(); + if (auto NACG2 = getBaseAsCopyGuardOrNull(NewDepPtr)) { + assert(NACG2 == NACG && "llvm.noalias.copy.guard dep must be identical"); + (void)NACG2; + NewDepPtr = detachFromNoAliasCopyGuard( + cast(Load->getPointerOperand()), NACG); + Load->setOperand(Load->getPointerOperandIndex(), NewDepPtr); + } + + if (Load->getType()->isPointerTy()) { + auto *NoAlias = IRB.CreateNoAliasPointer( + Load, NoAliasDecl, NewDepPtr, ScopeArg, Load->getName() + ".noalias"); + auto *NoAliasInstr = isa(NoAlias) + ? cast(NoAlias->getOperand(0)) + : NoAlias; + if (NoAliasDecl == OldNoAliasDecl) { + assert(NewNoAliasDecl->getOperand(Intrinsic::NoAliasDeclScopeArg) == + ScopeArg && + "New llvm.noalias.decl must have same scope"); + NoAliasInstr->setOperand(Intrinsic::NoAliasNoAliasDeclArg, + NewNoAliasDecl); + NoAliasInstr->setOperand( + Intrinsic::NoAliasIdentifyPObjIdArg, + NewNoAliasDecl->getOperand(Intrinsic::NoAliasDeclObjIdArg)); + } + + LLVM_DEBUG(llvm::dbgs() << " introduce: " << *NoAliasInstr << "\n"); + if (NoAlias != NoAliasInstr) + LLVM_DEBUG(llvm::dbgs() << " introduce: " << *NoAlias << "\n"); + + return NoAlias; + } + + assert(false && "Need PtrToInt ?"); + return Load; + } + bool visitMemTransferInst(MemTransferInst &II) { // Rewriting of memory transfer instructions can be a bit tricky. We break // them into two categories: split intrinsics and unsplit intrinsics. @@ -3021,12 +3364,14 @@ Value *Src; if (VecTy && !IsWholeAlloca && !IsDest) { + // FIXME: should we handle noalias annotations here ? Src = IRB.CreateAlignedLoad(NewAI.getAllocatedType(), &NewAI, NewAI.getAlign(), "load"); Src = extractVector(IRB, Src, BeginIndex, EndIndex, "vec"); } else if (IntTy && !IsWholeAlloca && !IsDest) { - Src = IRB.CreateAlignedLoad(NewAI.getAllocatedType(), &NewAI, - NewAI.getAlign(), "load"); + LoadInst *Load = IRB.CreateAlignedLoad(NewAI.getAllocatedType(), &NewAI, + NewAI.getAlign(), "load"); + Src = maybeIntroduceNoAlias(Load, II.getSource()); Src = convertValue(DL, IRB, Src, IntTy); uint64_t Offset = NewBeginOffset - NewAllocaBeginOffset; Src = extractInteger(DL, IRB, Src, SubIntTy, Offset, "extract"); @@ -3037,7 +3382,7 @@ LLVMContext::MD_access_group}); if (AATags) Load->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset)); - Src = Load; + Src = maybeIntroduceNoAlias(Load, II.getSource()); } if (VecTy && !IsWholeAlloca && IsDest) { @@ -3059,13 +3404,130 @@ LLVMContext::MD_access_group}); if (AATags) Store->setAAMetadata(AATags.shift(NewBeginOffset - BeginOffset)); - LLVM_DEBUG(dbgs() << " to: " << *Store << "\n"); + LLVM_DEBUG(dbgs() << "(3) to: " << *Store << "\n"); return !II.isVolatile(); } - bool visitIntrinsicInst(IntrinsicInst &II) { - assert((II.isLifetimeStartOrEnd() || II.isDroppable()) && - "Unexpected intrinsic!"); + void prepareNoAliasDecl() { + OldNoAliasDecl = nullptr; + NewNoAliasDecl = nullptr; + for (auto U : OldAI.users()) { + IntrinsicInst *II = dyn_cast(U); + if (II && II->getIntrinsicID() == Intrinsic::noalias_decl) { + if (OldNoAliasDecl) { + // We alreay found a llvm.noalias.decl - leave it up to the visiter to + // propagate + OldNoAliasDecl = nullptr; + NewNoAliasDecl = nullptr; + break; + } + IRB.SetInsertPoint(II); + IRB.SetCurrentDebugLocation(II->getDebugLoc()); + IRB.getInserter().SetNamePrefix(Twine(NewAI.getName()) + + ".noalias.decl."); + + OldNoAliasDecl = II; + LLVM_DEBUG(dbgs() << "Found llvm.noalias.decl: " << *II << "\n"); + ConstantInt *OldId = cast( + II->getArgOperand(Intrinsic::NoAliasDeclObjIdArg)); + NewNoAliasDecl = cast(IRB.CreateNoAliasDeclaration( + &NewAI, NewAllocaBeginOffset + OldId->getZExtValue(), + II->getArgOperand(2))); + LLVM_DEBUG(dbgs() << "New llvm.noalias.decl: " << *NewNoAliasDecl + << "\n"); + // continue - it is possible we see multiple llvm.noalias.decl! + } + } + } + + bool visitNoAliasDeclIntrinsicInst(IntrinsicInst &II) { + assert(II.getIntrinsicID() == Intrinsic::noalias_decl); + LLVM_DEBUG(dbgs() << " original: " << II << "\n"); + Value *New; + if (OldNoAliasDecl) { + assert(OldNoAliasDecl == &II); + assert(NewNoAliasDecl != nullptr); + New = NewNoAliasDecl; + } else { + assert(NewNoAliasDecl == nullptr); + ConstantInt *OldId = + cast(II.getArgOperand(Intrinsic::NoAliasDeclObjIdArg)); + New = cast(IRB.CreateNoAliasDeclaration( + &NewAI, NewAllocaBeginOffset + OldId->getZExtValue(), + II.getArgOperand(2))); + } + (void)New; + LLVM_DEBUG(dbgs() << " to: " << *New << "\n"); + + // Record this instruction for deletion. + Pass.DeadInsts.push_back(&II); + + // nothing else to do - preparation was already done + return true; + } + + bool visitProvenanceNoAliasIntrinsicInst(IntrinsicInst &II) { + assert(II.getIntrinsicID() == Intrinsic::provenance_noalias); + assert(II.getArgOperand(Intrinsic::ProvenanceNoAliasIdentifyPArg) == + OldPtr); + LLVM_DEBUG(dbgs() << " original: " << II << "\n"); + if (II.getArgOperand(Intrinsic::ProvenanceNoAliasNoAliasDeclArg) == + OldNoAliasDecl) { + assert(OldNoAliasDecl && NewNoAliasDecl && + "If we get here, we must have an old and a new llvm.noalias.decl"); + II.setArgOperand(Intrinsic::ProvenanceNoAliasNoAliasDeclArg, + NewNoAliasDecl); + } + II.setArgOperand( + Intrinsic::ProvenanceNoAliasIdentifyPArg, + getNewAllocaSlicePtr( + IRB, II.getArgOperand(Intrinsic::ProvenanceNoAliasIdentifyPArg) + ->getType())); + if (NewAllocaBeginOffset > 0) { + Value *OldObjIdV = + II.getArgOperand(Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg); + auto NewObjId = ConstantInt::get( + OldObjIdV->getType(), + cast(OldObjIdV)->getZExtValue() + NewAllocaBeginOffset); + II.setArgOperand(Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg, NewObjId); + } + LLVM_DEBUG(dbgs() << " to: " << II << "\n"); + deleteIfTriviallyDead(OldPtr); + return true; + } + + bool visitNoAliasIntrinsicInst(IntrinsicInst &II) { + assert(II.getIntrinsicID() == Intrinsic::noalias); + assert(II.getArgOperand(Intrinsic::NoAliasIdentifyPArg) == OldPtr); + LLVM_DEBUG(dbgs() << " original: " << II << "\n"); + if (II.getArgOperand(Intrinsic::NoAliasNoAliasDeclArg) == OldNoAliasDecl) { + assert(OldNoAliasDecl && NewNoAliasDecl && + "If we get here, we must have an old and a new llvm.noalias.decl"); + II.setArgOperand(Intrinsic::NoAliasNoAliasDeclArg, NewNoAliasDecl); + } + II.setArgOperand( + Intrinsic::NoAliasIdentifyPArg, + getNewAllocaSlicePtr( + IRB, II.getArgOperand(Intrinsic::NoAliasIdentifyPArg)->getType())); + if (NewAllocaBeginOffset > 0) { + Value *OldObjIdV = II.getArgOperand(Intrinsic::NoAliasIdentifyPObjIdArg); + auto NewObjId = ConstantInt::get( + OldObjIdV->getType(), + cast(OldObjIdV)->getZExtValue() + NewAllocaBeginOffset); + II.setArgOperand(Intrinsic::NoAliasIdentifyPObjIdArg, NewObjId); + } + LLVM_DEBUG(dbgs() << " to: " << II << "\n"); + deleteIfTriviallyDead(OldPtr); + return true; + } + + bool visitNoAliasCopyGuardIntrinsicInst(IntrinsicInst &II) { + assert(II.getIntrinsicID() == Intrinsic::noalias_copy_guard); + return true; + } + + bool visitLifetimeIntrinsicInst(IntrinsicInst &II) { + assert(II.isLifetimeStartOrEnd()); LLVM_DEBUG(dbgs() << " original: " << II << "\n"); // Record this instruction for deletion. @@ -3109,6 +3571,25 @@ return true; } + bool visitIntrinsicInst(IntrinsicInst &II) { + switch (II.getIntrinsicID()) { + case Intrinsic::lifetime_start: + case Intrinsic::lifetime_end: + return visitLifetimeIntrinsicInst(II); + case Intrinsic::noalias_decl: + return visitNoAliasDeclIntrinsicInst(II); + case Intrinsic::noalias: + return visitNoAliasIntrinsicInst(II); + case Intrinsic::provenance_noalias: + return visitProvenanceNoAliasIntrinsicInst(II); + case Intrinsic::noalias_copy_guard: + return visitNoAliasCopyGuardIntrinsicInst(II); + default: + assert(false && "SROA: SliceRewriter: unhandled intrinsic"); + return false; + } + } + void fixLoadStoreAlign(Instruction &Root) { // This algorithm implements the same visitor loop as // hasUnsafePHIOrSelectUse, and fixes the alignment of each load @@ -3201,6 +3682,235 @@ namespace { +// Returns true if the indicices of the provided GEP are compatible with +// the indices in the llvm.noalias.copy.guard. +// - treatMissingIndicesAsZero: if the number of indices from the GEP +// is smaller, treat the missing indices as zero +// Note: A nullptr GEP can be combined with treatMissingIndicesAsZero=true +static bool areGepIndicesCompatibleWithCopyGuard( + const DataLayout &DL, GetElementPtrInst *GEP, + llvm::Instruction *CopyGuardII, bool treatMissingIndicesAsZero = false) { + assert(CopyGuardII && "We need a llvm.noalias.copy.guard"); + + MDNode *CopyGuardIndices = cast( + cast( + CopyGuardII->getOperand(Intrinsic::NoAliasCopyGuardIndicesArg)) + ->getMetadata()); + APInt GEPOffset(DL.getPointerSizeInBits(), 0); + if (GEP) { + if (!GEP->accumulateConstantOffset(DL, GEPOffset)) + return false; + } else if (!treatMissingIndicesAsZero) + return false; + + // Either we could compute the offset, or we use 0 + MatchOffset MO(GEPOffset.getZExtValue()); + gatherValidNoAliasPointerOffsets(MO, CopyGuardIndices); + return MO.wasMatched(); +} + +static Type *GetZeroIndexLeafType(Type *TypeToLoad) { + while (true) { + if (StructType *ST = dyn_cast(TypeToLoad)) { + TypeToLoad = ST->getElementType(0); + continue; + } + if (ArrayType *AT = dyn_cast(TypeToLoad)) { + TypeToLoad = AT->getElementType(); + continue; + } + if (VectorType *VT = dyn_cast(TypeToLoad)) { + TypeToLoad = VT->getElementType(); + continue; + } + break; + } + assert(TypeToLoad->isPointerTy() && "Only pointers can have noalias info"); + + return TypeToLoad; +} + +static void detachIfSingleUse(Value *What, Instruction *NACG) { + // Be on the safe side + Instruction *I = dyn_cast(What); + if (I && I->getNumUses() == 1 && I->getOperand(0) == NACG) { + I->setOperand(0, NACG->getOperand(0)); + } +} + +// Check if the load corresponds to a restrict pointer, as specified in the +// CopyGuard information. +// If so, add and return 'llvm.noalias' before the load. If the original load +// needs to be replaced, due to bitcasts, it is returned through the 'Load' +// argument. +static llvm::Instruction *introduceNoAliasWhenCopyGuardIndicesAreCompatible( + llvm::LoadInst *Load, llvm::Instruction *CopyGuardII, const DataLayout &DL, + SmallVector *TrackSliceUses = nullptr) { + Value *PtrOp = Load->getPointerOperand(); + + if (TrackSliceUses) + TrackSliceUses->push_back( + &Load->getOperandUse(Load->getPointerOperandIndex())); + + if (CopyGuardII == nullptr) + return Load; + + // Possible cases: + // 1) load ( gep ( CopyGuard) ) + if (GetElementPtrInst *GEP = dyn_cast(PtrOp)) { + if (areGepIndicesCompatibleWithCopyGuard(DL, GEP, CopyGuardII)) { + if (!Load->getType()->isPointerTy()) { + //@ FIXME: Not a pointer type ? avoid introducing the noalias + // This is like the load of union (which is part of a struct). + // The correct solution for this should be to keep the + // llvm.noalias.copy.guard but this shift the offset with the gepoffset + // (But a negative shift is not yet supported in the NoAliasOffsets + // representation). + return Load; + } + + IRBuilderTy IRB(Load->getNextNode()); + + detachIfSingleUse(GEP, CopyGuardII); + + // A compatible set of indices was found - introduce a noalias intrinsic + // FIXME: what AAMetadata should we put on the llvm.noalias ? + auto NoAlias = IRB.CreateNoAliasPointer( + Load, + CopyGuardII->getOperand(Intrinsic::NoAliasCopyGuardNoAliasDeclArg), + GEP, CopyGuardII->getOperand(Intrinsic::NoAliasCopyGuardScopeArg), + Load->getName() + ".noalias"); + // juggle around + Load->replaceAllUsesWith(NoAlias); + NoAlias->setOperand(0, Load); + LLVM_DEBUG(llvm::dbgs() + << " - compatible, introduced:" << *NoAlias << "\n"); + + if (TrackSliceUses) + TrackSliceUses->push_back( + &NoAlias->getOperandUse(Intrinsic::NoAliasIdentifyPArg)); + + return NoAlias; + } + + return Load; + } + + if (BitCastInst *BCI = dyn_cast(PtrOp)) { + // We want to pass it as an integer type or pointer + if (!(Load->getType()->isIntegerTy() || Load->getType()->isPointerTy())) { + LLVM_DEBUG(llvm::dbgs() + << " ** copy.guard: ignoring non integer or pointer:" << *Load + << "\n"); + return Load; + } + + bool IsLoadOfInteger = Load->getType()->isIntegerTy(); + + // 2) load iXX (bitcast (gep (CopyGuard))) + // load pXX (bitcast (gep (CopyGuard))) + // 3) load iXX (bitcast (CopyGuard)) + // load pXX (bitcast (CopyGuard)) + Value *BCIOp = BCI->getOperand(0); + GetElementPtrInst *GEP = dyn_cast(BCI->getOperand(0)); + if (GEP || (BCIOp == CopyGuardII)) { + Type *TypeToLoad = BCIOp->getType()->getPointerElementType(); + + // Also handles a null GEP + if (!areGepIndicesCompatibleWithCopyGuard(DL, GEP, CopyGuardII, true)) { + return Load; + } + + TypeToLoad = GetZeroIndexLeafType(TypeToLoad); + + // Sizes must be identical + if (DL.getTypeStoreSizeInBits(TypeToLoad) != + DL.getTypeStoreSizeInBits(Load->getType())) { + LLVM_DEBUG(llvm::dbgs() << " ** copy.guard: type sizes do not match\n"); + return Load; + } + + IRBuilderTy IRB(Load->getNextNode()); + + if (GEP) { + detachIfSingleUse(GEP, CopyGuardII); + } else { + // Look through BCIop == CopyGuardII + BCIOp = CopyGuardII->getOperand(0); + } + + LLVM_DEBUG( + llvm::dbgs() + << (GEP ? " - compatible bitcast(gep(copy.guard)), introduced:\n" + : " - compatible bitcast(copy.guard), introduced:\n")); + + LoadInst *NewLoad = Load; + Value *NewPtr = BCIOp; + if (IsLoadOfInteger) { + NewPtr = IRB.CreatePointerBitCastOrAddrSpaceCast( + BCIOp, TypeToLoad->getPointerTo()); + + if (NewPtr != BCIOp) { + LLVM_DEBUG(llvm::dbgs() << " -- " << *NewPtr << "\n"); + } + + NewLoad = IRB.CreateAlignedLoad(TypeToLoad, NewPtr, Load->getAlign(), + Load->getName() + ".sroa_as_ptr"); + NewLoad->setAAMetadata(Load->getAAMetadata()); + LLVM_DEBUG(llvm::dbgs() << " -- " << *NewLoad << "\n"); + } + + // A compatible set of indices was found - introduce a noalias intrinsic + // FIXME: what AAMetadata should we put on the llvm.noalias ? + auto NoAlias = IRB.CreateNoAliasPointer( + NewLoad, + CopyGuardII->getOperand(Intrinsic::NoAliasCopyGuardNoAliasDeclArg), + NewPtr, CopyGuardII->getOperand(Intrinsic::NoAliasCopyGuardScopeArg), + NewLoad->getName() + ".noalias"); + + LLVM_DEBUG(llvm::dbgs() << " -- " << *NoAlias << "\n"); + Value *RetVal; + if (IsLoadOfInteger) { + auto PtrCast = IRB.CreatePtrToInt(NoAlias, Load->getType(), + Load->getName() + ".sroa_as_int"); + + LLVM_DEBUG(llvm::dbgs() << " -- " << *PtrCast << "\n"); + + // juggle around + Load->replaceAllUsesWith(PtrCast); + Load->eraseFromParent(); + + RetVal = PtrCast; + } else { + Load->replaceAllUsesWith(NoAlias); + NoAlias->setOperand(0, Load); // Set back the original op0. + + RetVal = NoAlias; + } + + if (BCI->use_empty()) + BCI->eraseFromParent(); + + if (TrackSliceUses) { + TrackSliceUses->back() = + &NewLoad->getOperandUse(NewLoad->getPointerOperandIndex()); + TrackSliceUses->push_back( + &NoAlias->getOperandUse(Intrinsic::NoAliasIdentifyPArg)); + } + + return cast(RetVal); + } + + LLVM_DEBUG(llvm::dbgs() + << " ** copy.guard: unhandled bitcast:" << BCI << "\n"); + return Load; + } + + LLVM_DEBUG(llvm::dbgs() << "copy.guard: unhandled:" << Load << "\n"); + // unhandled other situation + return Load; +} + /// Visitor to rewrite aggregate loads and stores as scalar. /// /// This pass aggressively rewrites all aggregate loads and stores on @@ -3209,6 +3919,7 @@ class AggLoadStoreRewriter : public InstVisitor { // Befriend the base class so it can delegate to private visit methods. friend class InstVisitor; + typedef InstVisitor Base; /// Queue of pointer uses to analyze and potentially rewrite. SmallVector Queue; @@ -3343,43 +4054,71 @@ struct LoadOpSplitter : public OpSplitter { AAMDNodes AATags; + Instruction *CopyGuardII = nullptr; + unsigned CGIIndex = 0; LoadOpSplitter(Instruction *InsertionPoint, Value *Ptr, Type *BaseTy, - AAMDNodes AATags, Align BaseAlign, const DataLayout &DL) + AAMDNodes AATags, Align BaseAlign, const DataLayout &DL, + Instruction *CopyGuardII_) : OpSplitter(InsertionPoint, Ptr, BaseTy, BaseAlign, DL), - AATags(AATags) {} + AATags(AATags), CopyGuardII(CopyGuardII_) {} /// Emit a leaf load of a single value. This is called at the leaves of the /// recursive emission to actually load values. void emitFunc(Type *Ty, Value *&Agg, Align Alignment, const Twine &Name) { assert(Ty->isSingleValueType()); // Load the single value and insert it using the indices. + auto Ptr = this->Ptr; // Make sure _NOT_ to overwrite the Ptr member + if (CopyGuardII) { + assert(CopyGuardII == Ptr && "Ptr != CopyGuardII ???"); + Ptr = CopyGuardII->getOperand(0); // look through noalias.copy.guard + } Value *GEP = IRB.CreateInBoundsGEP(BaseTy, Ptr, GEPIndices, Name + ".gep"); - LoadInst *Load = + Instruction *PValue; + LoadInst *PLoad = IRB.CreateAlignedLoad(Ty, GEP, Alignment, Name + ".load"); APInt Offset( DL.getIndexSizeInBits(Ptr->getType()->getPointerAddressSpace()), 0); if (AATags && GEPOperator::accumulateConstantOffset(BaseTy, GEPIndices, DL, Offset)) - Load->setAAMetadata(AATags.shift(Offset.getZExtValue())); + PLoad->setAAMetadata(AATags.shift(Offset.getZExtValue())); + PValue = introduceNoAliasWhenCopyGuardIndicesAreCompatible( + PLoad, CopyGuardII, DL); - Agg = IRB.CreateInsertValue(Agg, Load, Indices, Name + ".insert"); - LLVM_DEBUG(dbgs() << " to: " << *Load << "\n"); + Agg = IRB.CreateInsertValue(Agg, PValue, Indices, Name + ".insert"); + LLVM_DEBUG(dbgs() << " to: " << *PValue << "\n"); } }; bool visitLoadInst(LoadInst &LI) { - assert(LI.getPointerOperand() == *U); - if (!LI.isSimple() || LI.getType()->isSingleValueType()) + if (U->getOperandNo() == LI.getNoaliasProvenanceOperandIndex()) { + // Skip provenance + assert(LI.hasNoaliasProvenanceOperand() && + LI.getNoaliasProvenanceOperand() == *U); return false; + } + assert(LI.getPointerOperand() == *U); + Instruction *CopyGuardII = getBaseAsCopyGuardOrNull(LI.getPointerOperand()); + if (CopyGuardII) { + LLVM_DEBUG(llvm::dbgs() << " Replacing Load:" << LI + << "\n" + " Depends on:" + << *CopyGuardII << "\n"); + } + if (!LI.isSimple() || LI.getType()->isSingleValueType()) { + LoadInst *PLI = &LI; + auto Load = introduceNoAliasWhenCopyGuardIndicesAreCompatible( + PLI, CopyGuardII, DL); + return (Load != PLI); + } // We have an aggregate being loaded, split it apart. LLVM_DEBUG(dbgs() << " original: " << LI << "\n"); LoadOpSplitter Splitter(&LI, *U, LI.getType(), LI.getAAMetadata(), - getAdjustedAlignment(&LI, 0), DL); + getAdjustedAlignment(&LI, 0), DL, CopyGuardII); Value *V = UndefValue::get(LI.getType()); Splitter.emitSplitOps(LI.getType(), V, LI.getName() + ".fca"); Visited.erase(&LI); @@ -3429,6 +4168,16 @@ // We have an aggregate being stored, split it apart. LLVM_DEBUG(dbgs() << " original: " << SI << "\n"); + + if (auto *LI = dyn_cast(SI.getValueOperand())) { + // Try to split up the depending load, helpful for tracking noalias info + if (Visited.insert(LI).second) { + LLVM_DEBUG(llvm::dbgs() + << " - Forcing split of of StoreInst value operand\n"); + Queue.push_back(&LI->getOperandUse(LI->getPointerOperandIndex())); + } + } + StoreOpSplitter Splitter(&SI, *U, V->getType(), SI.getAAMetadata(), getAdjustedAlignment(&SI, 0), DL); Splitter.emitSplitOps(V->getType(), V, V->getName() + ".fca"); @@ -3442,6 +4191,30 @@ return false; } + // Look through noalias intrinsics + bool visitIntrinsicInst(IntrinsicInst &II) { + if (II.getIntrinsicID() == Intrinsic::noalias) { + if (II.getOperand(0) == *U) { + enqueueUsers(II); + } + return false; + } + if (II.getIntrinsicID() == Intrinsic::provenance_noalias || + II.getIntrinsicID() == Intrinsic::noalias_decl) { + return false; + } + if (II.getIntrinsicID() == Intrinsic::noalias_copy_guard) { + LLVM_DEBUG(llvm::dbgs() + << "AggLoadStoreRewriter: handling llvm.noalias.copy.guard:" + << (II.getOperand(0) == *U) << ":" << II << "\n"); + if (II.getOperand(0) == *U) + enqueueUsers(II); + return false; + } + + return Base::visitIntrinsicInst(II); + } + bool visitAddrSpaceCastInst(AddrSpaceCastInst &ASC) { enqueueUsers(ASC); return false; @@ -3950,8 +4723,8 @@ // First, we rewrite all of the split loads, and just accumulate each split // load in a parallel structure. We also build the slices for them and append // them to the alloca slices. - SmallDenseMap, 1> SplitLoadsMap; - std::vector SplitLoads; + SmallDenseMap, 1> SplitLoadsMap; + std::vector SplitLoads; const DataLayout &DL = AI.getModule()->getDataLayout(); for (LoadInst *LI : Loads) { SplitLoads.clear(); @@ -3971,6 +4744,8 @@ Instruction *BasePtr = cast(LI->getPointerOperand()); IRB.SetInsertPoint(LI); + Instruction *CopyGuardII = getBaseAsCopyGuardOrNull(BasePtr); + LLVM_DEBUG(dbgs() << " Splitting load: " << *LI << "\n"); uint64_t PartOffset = 0, PartSize = Offsets.Splits.front(); @@ -3989,18 +4764,23 @@ PLoad->copyMetadata(*LI, {LLVMContext::MD_mem_parallel_loop_access, LLVMContext::MD_access_group}); + SmallVector UsesToTrack; + auto *PValue = introduceNoAliasWhenCopyGuardIndicesAreCompatible( + PLoad, CopyGuardII, DL, &UsesToTrack); + // Append this load onto the list of split loads so we can find it later // to rewrite the stores. - SplitLoads.push_back(PLoad); + SplitLoads.push_back(PValue); // Now build a new slice for the alloca. - NewSlices.push_back( - Slice(BaseOffset + PartOffset, BaseOffset + PartOffset + PartSize, - &PLoad->getOperandUse(PLoad->getPointerOperandIndex()), - /*IsSplittable*/ false)); - LLVM_DEBUG(dbgs() << " new slice [" << NewSlices.back().beginOffset() - << ", " << NewSlices.back().endOffset() - << "): " << *PLoad << "\n"); + for (Use *PUse : UsesToTrack) { + NewSlices.push_back(Slice(BaseOffset + PartOffset, + BaseOffset + PartOffset + PartSize, PUse, + /*IsSplittable*/ false)); + LLVM_DEBUG(dbgs() << " new slice [" << NewSlices.back().beginOffset() + << ", " << NewSlices.back().endOffset() + << "): " << *PUse->getUser() << "\n"); + } // See if we've handled all the splits. if (Idx >= Size) @@ -4031,7 +4811,7 @@ LLVM_DEBUG(dbgs() << " Splitting store of load: " << *SI << "\n"); for (int Idx = 0, Size = SplitLoads.size(); Idx < Size; ++Idx) { - LoadInst *PLoad = SplitLoads[Idx]; + auto *PLoad = SplitLoads[Idx]; uint64_t PartOffset = Idx == 0 ? 0 : Offsets.Splits[Idx - 1]; auto *PartPtrTy = PLoad->getType()->getPointerTo(SI->getPointerAddressSpace()); @@ -4094,13 +4874,14 @@ "Cannot represent alloca access size using 64-bit integers!"); Value *LoadBasePtr = LI->getPointerOperand(); + Instruction *CopyGuardII = getBaseAsCopyGuardOrNull(LoadBasePtr); Instruction *StoreBasePtr = cast(SI->getPointerOperand()); LLVM_DEBUG(dbgs() << " Splitting store: " << *SI << "\n"); // Check whether we have an already split load. auto SplitLoadsMapI = SplitLoadsMap.find(LI); - std::vector *SplitLoads = nullptr; + std::vector *SplitLoads = nullptr; if (SplitLoadsMapI != SplitLoadsMap.end()) { SplitLoads = &SplitLoadsMapI->second; assert(SplitLoads->size() == Offsets.Splits.size() + 1 && @@ -4117,21 +4898,23 @@ auto *StorePartPtrTy = PartTy->getPointerTo(SI->getPointerAddressSpace()); // Either lookup a split load or create one. - LoadInst *PLoad; + Instruction *PLoad; if (SplitLoads) { PLoad = (*SplitLoads)[Idx]; } else { IRB.SetInsertPoint(LI); auto AS = LI->getPointerAddressSpace(); - PLoad = IRB.CreateAlignedLoad( + LoadInst *NewPLoad = IRB.CreateAlignedLoad( PartTy, getAdjustedPtr(IRB, DL, LoadBasePtr, APInt(DL.getIndexSizeInBits(AS), PartOffset), LoadPartPtrTy, LoadBasePtr->getName() + "."), getAdjustedAlignment(LI, PartOffset), /*IsVolatile*/ false, LI->getName()); - PLoad->copyMetadata(*LI, {LLVMContext::MD_mem_parallel_loop_access, + NewPLoad->copyMetadata(*LI, {LLVMContext::MD_mem_parallel_loop_access, LLVMContext::MD_access_group}); + PLoad = introduceNoAliasWhenCopyGuardIndicesAreCompatible( + NewPLoad, CopyGuardII, DL); } // And store this partition. @@ -4242,6 +5025,7 @@ // or an i8 array of an appropriate size. Type *SliceTy = nullptr; const DataLayout &DL = AI.getModule()->getDataLayout(); + auto RepresentsNoAlias = (partitionRepresentsNoAliasPointer(P) != nullptr); std::pair CommonUseTy = findCommonType(P.begin(), P.end(), P.endOffset()); // Do all uses operate on the same type? @@ -4272,6 +5056,14 @@ if (VecTy) SliceTy = VecTy; + if (RepresentsNoAlias && !SliceTy->isPointerTy()) { + if (DL.getTypeStoreSizeInBits(SliceTy) == + DL.getTypeStoreSizeInBits(SliceTy->getPointerTo())) { + // a restrict pointer must be a pointer + SliceTy = SliceTy->getPointerTo(); + } + } + // Check for the case where we're going to rewrite to a new alloca of the // exact same type as the original, and with the same access offsets. In that // case, re-use the existing alloca, but still run through the rewriter to @@ -4313,7 +5105,7 @@ AllocaSliceRewriter Rewriter(DL, AS, *this, AI, *NewAI, P.beginOffset(), P.endOffset(), IsIntegerPromotable, VecTy, - PHIUsers, SelectUsers); + PHIUsers, SelectUsers, RepresentsNoAlias); bool Promotable = true; for (Slice *S : P.splitSliceTails()) { Promotable &= Rewriter.visit(S); @@ -4579,6 +5371,7 @@ /// rewritten as needed. bool SROAPass::runOnAlloca(AllocaInst &AI) { LLVM_DEBUG(dbgs() << "SROA alloca: " << AI << "\n"); + LLVM_DEBUG(AI.getParent()->getParent()->dump()); ++NumAllocasAnalyzed; // Special case dead allocas, as they're trivial. Index: llvm/lib/Transforms/Scalar/Scalar.cpp =================================================================== --- llvm/lib/Transforms/Scalar/Scalar.cpp +++ llvm/lib/Transforms/Scalar/Scalar.cpp @@ -38,6 +38,7 @@ initializeBDCELegacyPassPass(Registry); initializeAlignmentFromAssumptionsPass(Registry); initializeCallSiteSplittingLegacyPassPass(Registry); + initializeConnectNoAliasDeclLegacyPassPass(Registry); initializeConstantHoistingLegacyPassPass(Registry); initializeConstraintEliminationPass(Registry); initializeCorrelatedValuePropagationPass(Registry); @@ -92,6 +93,7 @@ initializeMergedLoadStoreMotionLegacyPassPass(Registry); initializeNaryReassociateLegacyPassPass(Registry); initializePartiallyInlineLibCallsLegacyPassPass(Registry); + initializePropagateAndConvertNoAliasLegacyPassPass(Registry); initializeReassociateLegacyPassPass(Registry); initializeRedundantDbgInstEliminationPass(Registry); initializeRegToMemLegacyPass(Registry); Index: llvm/lib/Transforms/Utils/CMakeLists.txt =================================================================== --- llvm/lib/Transforms/Utils/CMakeLists.txt +++ llvm/lib/Transforms/Utils/CMakeLists.txt @@ -52,6 +52,7 @@ MetaRenamer.cpp ModuleUtils.cpp NameAnonGlobals.cpp + NoAliasUtils.cpp PredicateInfo.cpp PromoteMemoryToRegister.cpp RelLookupTableConverter.cpp Index: llvm/lib/Transforms/Utils/CloneFunction.cpp =================================================================== --- llvm/lib/Transforms/Utils/CloneFunction.cpp +++ llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -39,6 +39,21 @@ #define DEBUG_TYPE "clone-function" +static void PropagateNoAliasProvenanceInfo(Instruction *To, + const Instruction *From) { + // The ptr_provenance is not automatically copied over in a 'clone()' + // Let's do it here. + if (auto *LI = dyn_cast(From)) { + if (LI->hasNoaliasProvenanceOperand()) + cast(To)->setNoaliasProvenanceOperand( + LI->getNoaliasProvenanceOperand()); + } else if (auto SI = dyn_cast(From)) { + if (SI->hasNoaliasProvenanceOperand()) + cast(To)->setNoaliasProvenanceOperand( + SI->getNoaliasProvenanceOperand()); + } +} + /// See comments in Cloning.h. BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix, Function *F, @@ -57,6 +72,8 @@ DIFinder->processInstruction(*TheModule, I); Instruction *NewInst = I.clone(); + PropagateNoAliasProvenanceInfo(NewInst, &I); + if (I.hasName()) NewInst->setName(I.getName() + NameSuffix); NewBB->getInstList().push_back(NewInst); @@ -380,6 +397,7 @@ ++II) { Instruction *NewInst = II->clone(); + PropagateNoAliasProvenanceInfo(NewInst, &*II); // Eagerly remap operands to the newly cloned instruction, except for PHI // nodes for which we defer processing until we update the CFG. @@ -913,6 +931,7 @@ // terminator gets replaced and StopAt == BB's terminator. for (; StopAt != &*BI && BB->getTerminator() != &*BI; ++BI) { Instruction *New = BI->clone(); + PropagateNoAliasProvenanceInfo(New, &*BI); New->setName(BI->getName()); New->insertBefore(NewTerm); ValueMapping[&*BI] = New; @@ -975,9 +994,31 @@ return nullptr; }; - if (auto *Decl = dyn_cast(I)) + if (auto *Decl = dyn_cast(I)) { if (auto *NewScopeList = CloneScopeList(Decl->getScopeList())) Decl->setScopeList(NewScopeList); + } else if (auto *II = dyn_cast(I)) { + auto ID = II->getIntrinsicID(); + if (ID == Intrinsic::noalias || ID == Intrinsic::provenance_noalias || + ID == Intrinsic::noalias_decl || ID == Intrinsic::noalias_copy_guard) { + int NoAliasScope = 0; + if (ID == Intrinsic::noalias) + NoAliasScope = Intrinsic::NoAliasScopeArg; + if (ID == Intrinsic::provenance_noalias) + NoAliasScope = Intrinsic::ProvenanceNoAliasScopeArg; + if (ID == Intrinsic::noalias_decl) + NoAliasScope = Intrinsic::NoAliasDeclScopeArg; + if (ID == Intrinsic::noalias_copy_guard) + NoAliasScope = Intrinsic::NoAliasCopyGuardScopeArg; + + if (auto *NewScopeList = CloneScopeList( + cast(cast(II->getOperand(NoAliasScope)) + ->getMetadata()))) { + II->setOperand(NoAliasScope, + MetadataAsValue::get(II->getContext(), NewScopeList)); + } + } + } auto replaceWhenNeeded = [&](unsigned MD_ID) { if (const MDNode *CSNoAlias = I->getMetadata(MD_ID)) @@ -1031,6 +1072,13 @@ for (Instruction &I : *BB) if (auto *Decl = dyn_cast(&I)) NoAliasDeclScopes.push_back(Decl->getScopeList()); + else if (auto CB = dyn_cast(&I)) { + if (CB->getIntrinsicID() == Intrinsic::noalias_decl) + NoAliasDeclScopes.push_back( + dyn_cast(cast( + I.getOperand(Intrinsic::NoAliasDeclScopeArg)) + ->getMetadata())); + } } void llvm::identifyNoAliasScopesToClone( @@ -1039,4 +1087,10 @@ for (Instruction &I : make_range(Start, End)) if (auto *Decl = dyn_cast(&I)) NoAliasDeclScopes.push_back(Decl->getScopeList()); + else if (auto CB = dyn_cast(&I)) { + if (CB->getIntrinsicID() == Intrinsic::noalias_decl) + NoAliasDeclScopes.push_back(dyn_cast( + cast(I.getOperand(Intrinsic::NoAliasDeclScopeArg)) + ->getMetadata())); + } } Index: llvm/lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- llvm/lib/Transforms/Utils/InlineFunction.cpp +++ llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -46,6 +46,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" +#include "llvm/IR/InstIterator.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" @@ -64,6 +65,7 @@ #include "llvm/Transforms/Utils/AssumeBundleBuilder.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Transforms/Utils/NoAliasUtils.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include #include @@ -82,11 +84,15 @@ cl::Hidden, cl::desc("Convert noalias attributes to metadata during inlining.")); -static cl::opt - UseNoAliasIntrinsic("use-noalias-intrinsic-during-inlining", cl::Hidden, - cl::ZeroOrMore, cl::init(true), - cl::desc("Use the llvm.experimental.noalias.scope.decl " - "intrinsic during inlining.")); +enum NoAliasIntrinsicKind { NAIK_none, NAIK_scopes, NAIK_full }; +static cl::opt UseNoAliasIntrinsic( + "use-noalias-intrinsic-during-inlining", cl::Hidden, cl::ZeroOrMore, + cl::init(NAIK_full), cl::desc("Use noalias intrinsics during inlining."), + cl::values(clEnumValN(NAIK_none, "none", "no intrinsics"), + clEnumValN(NAIK_scopes, "scopes", + "use llvm.experimental.noalias.scope.decl"), + clEnumValN(NAIK_full, "full", + "use llvm.noalias.decl (full restrict)"))); // Disabled by default, because the added alignment assumptions may increase // compile-time and block optimizations. This option is not suitable for use @@ -788,44 +794,72 @@ /// When inlining a call site that has !llvm.mem.parallel_loop_access, /// !llvm.access.group, !alias.scope or !noalias metadata, that metadata should /// be propagated to all memory-accessing cloned instructions. -static void PropagateCallSiteMetadata(CallBase &CB, Function::iterator FStart, - Function::iterator FEnd) { +static void +PropagateCallSiteMetadata(CallBase &CB, MDNode *NewNoAliasScopeList, + const SmallVectorImpl &NewNoAliasInst, + Function::iterator FStart, Function::iterator FEnd) { MDNode *MemParallelLoopAccess = CB.getMetadata(LLVMContext::MD_mem_parallel_loop_access); MDNode *AccessGroup = CB.getMetadata(LLVMContext::MD_access_group); MDNode *AliasScope = CB.getMetadata(LLVMContext::MD_alias_scope); - MDNode *NoAlias = CB.getMetadata(LLVMContext::MD_noalias); + MDNode *NoAlias = MDNode::concatenate(CB.getMetadata(LLVMContext::MD_noalias), + NewNoAliasScopeList); if (!MemParallelLoopAccess && !AccessGroup && !AliasScope && !NoAlias) return; - for (BasicBlock &BB : make_range(FStart, FEnd)) { - for (Instruction &I : BB) { - // This metadata is only relevant for instructions that access memory. - if (!I.mayReadOrWriteMemory()) - continue; - - if (MemParallelLoopAccess) { - // TODO: This probably should not overwrite MemParalleLoopAccess. - MemParallelLoopAccess = MDNode::concatenate( - I.getMetadata(LLVMContext::MD_mem_parallel_loop_access), - MemParallelLoopAccess); - I.setMetadata(LLVMContext::MD_mem_parallel_loop_access, - MemParallelLoopAccess); + auto AdaptMetaData = [&](Instruction &I) { + if (NoAlias) { + // FIXME: should we handle AliasScope metadata on noalias intrinsics ? + if (auto *II = dyn_cast(&I)) { + auto ID = II->getIntrinsicID(); + if (ID == Intrinsic::noalias || ID == Intrinsic::noalias_decl || + ID == Intrinsic::provenance_noalias || + ID == Intrinsic::noalias_copy_guard) { + I.setMetadata(LLVMContext::MD_noalias, + MDNode::concatenate( + I.getMetadata(LLVMContext::MD_noalias), NoAlias)); + return; + } } + } - if (AccessGroup) - I.setMetadata(LLVMContext::MD_access_group, uniteAccessGroups( - I.getMetadata(LLVMContext::MD_access_group), AccessGroup)); + // This metadata is only relevant for instructions that access memory. + if (!I.mayReadOrWriteMemory()) + return; + + if (MemParallelLoopAccess) { + // TODO: This probably should not overwrite MemParalleLoopAccess. + MemParallelLoopAccess = MDNode::concatenate( + I.getMetadata(LLVMContext::MD_mem_parallel_loop_access), + MemParallelLoopAccess); + I.setMetadata(LLVMContext::MD_mem_parallel_loop_access, + MemParallelLoopAccess); + } - if (AliasScope) - I.setMetadata(LLVMContext::MD_alias_scope, MDNode::concatenate( - I.getMetadata(LLVMContext::MD_alias_scope), AliasScope)); + if (AccessGroup) + I.setMetadata( + LLVMContext::MD_access_group, + uniteAccessGroups(I.getMetadata(LLVMContext::MD_access_group), + AccessGroup)); + + if (AliasScope) + I.setMetadata( + LLVMContext::MD_alias_scope, + MDNode::concatenate(I.getMetadata(LLVMContext::MD_alias_scope), + AliasScope)); + + if (NoAlias) + I.setMetadata( + LLVMContext::MD_noalias, + MDNode::concatenate(I.getMetadata(LLVMContext::MD_noalias), NoAlias)); + }; - if (NoAlias) - I.setMetadata(LLVMContext::MD_noalias, MDNode::concatenate( - I.getMetadata(LLVMContext::MD_noalias), NoAlias)); - } - } + for (Instruction *NI : NewNoAliasInst) + AdaptMetaData(*NI); + + for (BasicBlock &BB : make_range(FStart, FEnd)) + for (Instruction &I : BB) + AdaptMetaData(I); } namespace { @@ -837,23 +871,56 @@ using MetadataMap = DenseMap; SetVector MD; MetadataMap MDMap; + MDNode *CallerNoAlias = nullptr; + MDNode *CalleeNoAlias = nullptr; + MDNode *NewUnknownScope = nullptr; void addRecursiveMetadataUses(); public: - ScopedAliasMetadataDeepCloner(const Function *F); + ScopedAliasMetadataDeepCloner(Function *F, Function *Caller); /// Create a new clone of the scoped alias metadata, which will be used by /// subsequent remap() calls. - void clone(); + void clone(LLVMContext &Context); /// Remap instructions in the given range from the original to the cloned /// metadata. void remap(Function::iterator FStart, Function::iterator FEnd); + + /// Update all memory instructions with the new unknown scope. + void updateNewUnknownScope(Function *Caller); }; } // namespace -ScopedAliasMetadataDeepCloner::ScopedAliasMetadataDeepCloner( - const Function *F) { +ScopedAliasMetadataDeepCloner::ScopedAliasMetadataDeepCloner(Function *F, + Function *Caller) { + const auto *CalledFunc = F; + + // Track function level !noalias metadata ('unknown function' scope). This + // should be merged with the data from the callee. + CallerNoAlias = Caller->getMetadata("noalias"); + CalleeNoAlias = CalledFunc->getMetadata("noalias"); + + if ((CalleeNoAlias != nullptr) && (CallerNoAlias == nullptr)) { + // - NOTE: keep in sync with (clang) CGExpr: EmitLoadOfScalar + // - NOTE: keep in sync with (clang) CGDecl: EmitAutoVarNoAlias + // - EmitNoAliasDecl + // - NOTE: keep in sync with (llvm) InlineFunction: CloneAliasScopeMetadata + llvm::MDBuilder MDB(Caller->getContext()); + std::string Name(Caller->getName()); + auto NoAliasDomain = MDB.createAnonymousAliasScopeDomain(Name); + Name += ": unknown scope"; + + llvm::MDNode *UnknownScope = + MDB.createAnonymousAliasScope(NoAliasDomain, Name); + + { + SmallVector ScopeListEntries(1, UnknownScope); + CallerNoAlias = llvm::MDNode::get(Caller->getContext(), ScopeListEntries); + Caller->setMetadata("noalias", CallerNoAlias); + } + NewUnknownScope = UnknownScope; + } for (const BasicBlock &BB : *F) { for (const Instruction &I : BB) { if (const MDNode *M = I.getMetadata(LLVMContext::MD_alias_scope)) @@ -864,6 +931,34 @@ // We also need to clone the metadata in noalias intrinsics. if (const auto *Decl = dyn_cast(&I)) MD.insert(Decl->getScopeList()); + + // We also need to clone the metadata in noalias intrinsics. + if (const auto *II = dyn_cast(&I)) { + if (II->getIntrinsicID() == Intrinsic::noalias) + if (const auto *M = dyn_cast( + cast( + II->getOperand(Intrinsic::NoAliasScopeArg)) + ->getMetadata())) + MD.insert(M); + if (II->getIntrinsicID() == Intrinsic::provenance_noalias) + if (const auto *M = dyn_cast( + cast( + II->getOperand(Intrinsic::ProvenanceNoAliasScopeArg)) + ->getMetadata())) + MD.insert(M); + if (II->getIntrinsicID() == Intrinsic::noalias_decl) + if (const auto *M = dyn_cast( + cast( + II->getOperand(Intrinsic::NoAliasDeclScopeArg)) + ->getMetadata())) + MD.insert(M); + if (II->getIntrinsicID() == Intrinsic::noalias_copy_guard) + if (const auto *M = dyn_cast( + cast( + II->getOperand(Intrinsic::NoAliasCopyGuardScopeArg)) + ->getMetadata())) + MD.insert(M); + } } } addRecursiveMetadataUses(); @@ -880,10 +975,17 @@ } } -void ScopedAliasMetadataDeepCloner::clone() { +void ScopedAliasMetadataDeepCloner::clone(LLVMContext &Context) { assert(MDMap.empty() && "clone() already called ?"); SmallVector DummyNodes; + if ((CalleeNoAlias != nullptr) && (CalleeNoAlias != CallerNoAlias)) { + // Map CalleeNoAlias onto CallerNoAlias + MD.remove(CalleeNoAlias); + DummyNodes.push_back(MDTuple::getTemporary(Context, None)); + MDMap[CalleeNoAlias].reset(DummyNodes.back().get()); + cast(MDMap[CalleeNoAlias])->replaceAllUsesWith(CallerNoAlias); + } for (const MDNode *I : MD) { DummyNodes.push_back(MDTuple::getTemporary(I->getContext(), None)); MDMap[I].reset(DummyNodes.back().get()); @@ -919,6 +1021,10 @@ for (Instruction &I : BB) { // TODO: The null checks for the MDMap.lookup() results should no longer // be necessary. + + // Only update scopes when we find them in the map. If they are not, it is + // because we already handled that instruction before. This is faster than + // tracking which instructions we already updated. if (MDNode *M = I.getMetadata(LLVMContext::MD_alias_scope)) if (MDNode *MNew = MDMap.lookup(M)) I.setMetadata(LLVMContext::MD_alias_scope, MNew); @@ -930,10 +1036,135 @@ if (auto *Decl = dyn_cast(&I)) if (MDNode *MNew = MDMap.lookup(Decl->getScopeList())) Decl->setScopeList(MNew); + + // Update the metadata referenced by a noalias intrinsic + if (auto *II = dyn_cast(&I)) { + auto ID = II->getIntrinsicID(); + if (ID == Intrinsic::noalias || ID == Intrinsic::provenance_noalias || + ID == Intrinsic::noalias_decl || + ID == Intrinsic::noalias_copy_guard) { + int NoAliasScope = 0; + if (ID == Intrinsic::noalias) + NoAliasScope = Intrinsic::NoAliasScopeArg; + if (ID == Intrinsic::provenance_noalias) + NoAliasScope = Intrinsic::ProvenanceNoAliasScopeArg; + if (ID == Intrinsic::noalias_decl) + NoAliasScope = Intrinsic::NoAliasDeclScopeArg; + if (ID == Intrinsic::noalias_copy_guard) + NoAliasScope = Intrinsic::NoAliasCopyGuardScopeArg; + + if (auto *M = dyn_cast( + cast(II->getOperand(NoAliasScope)) + ->getMetadata())) { + // If the metadata is not in the map, it could be a new intrinsic + // that was just added. + auto MI = MDMap.find(M); + if (MI != MDMap.end()) + II->setOperand(NoAliasScope, MetadataAsValue::get( + II->getContext(), MI->second)); + } + } + } + } + } +} + +void ScopedAliasMetadataDeepCloner::updateNewUnknownScope(Function *Caller) { + if (!NewUnknownScope) + return; + + // We now need to add the out-of-function scope to _all_ instructions with + // noalias data in the 'caller' + // Note: following strange choice of variables names is similar to how it is + // done later + // FIXME: hmm this might be less than fast :( + // hmm it is also needed to do this _after_ the metadata cloning, otherwise + // we seem to lose information ! + for (BasicBlock &I : *Caller) { + for (Instruction &J : I) { + if (const MDNode *M = J.getMetadata(LLVMContext::MD_noalias)) { + SmallVector NewScopeList; + for (auto &MDOp : M->operands()) { + NewScopeList.push_back(MDOp); + } + NewScopeList.push_back(NewUnknownScope); + J.setMetadata(LLVMContext::MD_noalias, + MDNode::get(Caller->getContext(), NewScopeList)); + } else if (J.mayReadOrWriteMemory()) { + // no Noalias, but we need to add the (new) 'unknown scope' ! + J.setMetadata(LLVMContext::MD_noalias, CallerNoAlias); + } } } } +/// If the inlined function has noalias arguments, +/// then add a new alias scope to instructions that might access memory, and +/// noalias intrinsics corresponding to the noalias arguments. +static void AddNoAliasIntrinsics(CallBase &CB, ValueToValueMapTy &VMap, + MDNode *&NewScopeList, + SmallVectorImpl &NewNoAlias) { + if (!EnableNoAliasConversion || (UseNoAliasIntrinsic != NAIK_full)) + return; + + const Function *CalledFunc = CB.getCalledFunction(); + SmallVector NoAliasArgs; + + for (const auto &Arg : CalledFunc->args()) { + if (CB.paramHasAttr(Arg.getArgNo(), Attribute::NoAlias) && !Arg.use_empty()) + NoAliasArgs.push_back(&Arg); + } + + if (NoAliasArgs.empty()) + return; + + MDBuilder MDB(CalledFunc->getContext()); + // Create a new scope domain for this function. + MDNode *NewDomain = + MDB.createAnonymousAliasScopeDomain(CalledFunc->getName()); + + // Create a new scope for each noalias argument. + SmallVector Scopes; + + // For each noalias argument, add a noalias intrinsic call, and update the + // value map to refer to the new result of the noalias call. + for (const Argument *A : NoAliasArgs) { + Value *MappedA = VMap[A]; + if (isa(MappedA)) { + // Skip generating restrict intrinsics for known 'null' pointers + continue; + } + + std::string Name(CalledFunc->getName()); + if (A->hasName()) { + Name += ": %"; + Name += A->getName(); + } else { + Name += ": argument "; + Name += utostr(A->getArgNo()); + } + + MDNode *AScope = MDB.createAnonymousAliasScope(NewDomain, Name); + Scopes.push_back(AScope); + + MDNode *AScopeList = MDNode::get(CalledFunc->getContext(), AScope); + + // The alloca was optimized away -> use a nullptr + auto *IdentifyPAlloca = + ConstantPointerNull::get(MappedA->getType()->getPointerTo()); + auto *NoAliasDecl = + IRBuilder<>(&CB).CreateNoAliasDeclaration(IdentifyPAlloca, AScopeList); + Value *NA = IRBuilder<>(&CB).CreateNoAliasPointer( + MappedA, NoAliasDecl, IdentifyPAlloca, AScopeList); + VMap[A] = NA; + // Ensure that PropagateCallSiteMetadata also tracks this instruction. + NewNoAlias.emplace_back(cast(NA)); + } + + if (!Scopes.empty()) + NewScopeList = MDNode::get(CalledFunc->getContext(), Scopes); +} + /// If the inlined function has noalias arguments, /// then add new alias scopes for each noalias argument, tag the mapped noalias /// parameters with noalias metadata specifying the new scope, and tag all @@ -941,7 +1172,7 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap, const DataLayout &DL, AAResults *CalleeAAR, ClonedCodeInfo &InlinedFunctionInfo) { - if (!EnableNoAliasConversion) + if (!EnableNoAliasConversion || (UseNoAliasIntrinsic != NAIK_scopes)) return; const Function *CalledFunc = CB.getCalledFunction(); @@ -989,7 +1220,7 @@ MDNode *NewScope = MDB.createAnonymousAliasScope(NewDomain, Name); NewScopes.insert(std::make_pair(A, NewScope)); - if (UseNoAliasIntrinsic) { + if (UseNoAliasIntrinsic == NAIK_scopes) { // FIXME: already checked at entry // Introduce a llvm.experimental.noalias.scope.decl for the noalias // argument. MDNode *AScopeList = MDNode::get(CalledFunc->getContext(), NewScope); @@ -1896,6 +2127,7 @@ }; // Keep a list of pair (dst, src) to emit byval initializations. SmallVector ByValInits; + MDNode *NAScopeList = nullptr; // When inlining a function that contains noalias scope metadata, // this metadata needs to be cloned so that the inlined blocks @@ -1903,7 +2135,8 @@ // Track the metadata that must be cloned. Do this before other changes to // the function, so that we do not get in trouble when inlining caller == // callee. - ScopedAliasMetadataDeepCloner SAMetadataCloner(CB.getCalledFunction()); + ScopedAliasMetadataDeepCloner SAMetadataCloner(CB.getCalledFunction(), + Caller); auto &DL = Caller->getParent()->getDataLayout(); @@ -1943,6 +2176,10 @@ /// Preserve all attributes on of the call and its parameters. salvageKnowledge(&CB, AC); + SmallVector NewNoAliasIntrinsics; + // Add noalias intrinsics corresponding to noalias function arguments. + AddNoAliasIntrinsics(CB, VMap, NAScopeList, NewNoAliasIntrinsics); + // We want the inliner to prune the code as it copies. We would LOVE to // have no dead or constant instructions leftover after inlining occurs // (which can happen, e.g., because an argument was constant), but we'll be @@ -2037,8 +2274,9 @@ CalledFunc->getSubprogram() != nullptr); // Now clone the inlined noalias scope metadata. - SAMetadataCloner.clone(); + SAMetadataCloner.clone(CalledFunc->getContext()); SAMetadataCloner.remap(FirstNewBlock, Caller->end()); + SAMetadataCloner.updateNewUnknownScope(Caller); // Add noalias metadata if necessary. AddAliasScopeMetadata(CB, VMap, DL, CalleeAAR, InlinedFunctionInfo); @@ -2048,7 +2286,8 @@ AddReturnAttributes(CB, VMap); // Propagate metadata on the callsite if necessary. - PropagateCallSiteMetadata(CB, FirstNewBlock, Caller->end()); + PropagateCallSiteMetadata(CB, NAScopeList, NewNoAliasIntrinsics, + FirstNewBlock, Caller->end()); // Register any cloned assumptions. if (IFI.GetAssumptionCache) @@ -2490,6 +2729,9 @@ // Since we are now done with the return instruction, delete it also. Returns[0]->eraseFromParent(); + // Already try to connect llvm.noalias.decl where possible + propagateAndConnectNoAliasDecl(Caller); + // We are now done with the inlining. return InlineResult::success(); } @@ -2640,6 +2882,9 @@ // Now we can remove the CalleeEntry block, which is now empty. Caller->getBasicBlockList().erase(CalleeEntry); + // Already try to connect llvm.noalias.decl where possible + propagateAndConnectNoAliasDecl(Caller); + // If we inserted a phi node, check to see if it has a single value (e.g. all // the entries are the same or undef). If so, remove the PHI so it doesn't // block other optimizations. Index: llvm/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/lib/Transforms/Utils/Local.cpp +++ llvm/lib/Transforms/Utils/Local.cpp @@ -478,6 +478,29 @@ Optional ExBehavior = FPI->getExceptionBehavior(); return ExBehavior.getValue() != fp::ebStrict; } + + // noalias intrinsics are dead if they have no uses (they're tagged as + // writing, but that is only to maintain control dependencies, not because + // they actually write anything). + if (II->getIntrinsicID() == Intrinsic::noalias || + II->getIntrinsicID() == Intrinsic::provenance_noalias || + II->getIntrinsicID() == Intrinsic::noalias_copy_guard || + II->getIntrinsicID() == Intrinsic::noalias_arg_guard) + return II->use_empty(); + + // llvm.noalias.decl which operand only has a single use are trivially dead. + // NOTE: this assumes that noalias intrinsics nodes are never combined ! + if (II->getIntrinsicID() == Intrinsic::noalias_decl) { + auto *DAA = II->getOperand(Intrinsic::NoAliasDeclAllocaArg); + if (isa(DAA)) { + // no associated alloca -> if there are no uses, it is trivially dead + return II->getNumUses() == 0; + } else { + return (DAA->getNumUses() == 1) && + (II->getOperand(Intrinsic::NoAliasDeclScopeArg)->getNumUses() == + 1); + } + } } if (isAllocLikeFn(I, TLI)) Index: llvm/lib/Transforms/Utils/LoopPeel.cpp =================================================================== --- llvm/lib/Transforms/Utils/LoopPeel.cpp +++ llvm/lib/Transforms/Utils/LoopPeel.cpp @@ -38,6 +38,7 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/LoopSimplify.h" #include "llvm/Transforms/Utils/LoopUtils.h" +#include "llvm/Transforms/Utils/NoAliasUtils.h" #include "llvm/Transforms/Utils/UnrollLoop.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include @@ -821,6 +822,15 @@ SmallVector LoopLocalNoAliasDeclScopes; identifyNoAliasScopesToClone(L->getBlocks(), LoopLocalNoAliasDeclScopes); + if (!LoopLocalNoAliasDeclScopes.empty() && PeelCount) { + // We have loop local llvm.noalias.decl. If they are used by code that is + // considered to be outside the loop, the must go through the latch block. + // We duplicate the llvm.noalias.decl to the latch block, so that migrated + // code can still locally benefit from the noalias information. But it will + // get disconnected from the information inside the loop body itself. + llvm::cloneNoAliasDeclIntoExit(L); + } + // For each peeled-off iteration, make a copy of the loop. for (unsigned Iter = 0; Iter < PeelCount; ++Iter) { SmallVector NewBlocks; @@ -860,6 +870,13 @@ NewBlocks[0]->getIterator(), F->end()); } + { + // Also adapt the original scopes of the loop, as they must be disconnected + // from usages outside the loop. + cloneAndAdaptNoAliasScopes(LoopLocalNoAliasDeclScopes, L->getBlocks(), + Header->getContext(), "NotPeeled"); + } + // Now adjust the phi nodes in the loop header to get their initial values // from the last peeled-off iteration instead of the preheader. for (BasicBlock::iterator I = Header->begin(); isa(I); ++I) { Index: llvm/lib/Transforms/Utils/LoopRotationUtils.cpp =================================================================== --- llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -38,6 +38,7 @@ #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" +#include "llvm/Transforms/Utils/NoAliasUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Transforms/Utils/ValueMapper.h" using namespace llvm; @@ -403,13 +404,87 @@ break; } - // Remember the local noalias scope declarations in the header. After the - // rotation, they must be duplicated and the scope must be cloned. This - // avoids unwanted interaction across iterations. - SmallVector NoAliasDeclInstructions; - for (Instruction &I : *OrigHeader) - if (auto *Decl = dyn_cast(&I)) - NoAliasDeclInstructions.push_back(Decl); + // check if there are local restrict declarations and how they are used. + // - avoid breaking up mixed usage: + // -- either all usages must be in the OrigHeader, or no usages must be in + // the OrigHeader. + // -- when usages are outside the function, and we decide to continue, break + // the connection with the llvm.noalias.decl, as it will have no impact + // any more. + SmallVector NoAliasScopeDeclInstructions; + SmallVector NoAliasDeclInstructions; + { + SmallVector ProvenanceNoAliasOrNoAliasToDisconnect; + for (Instruction &I : *OrigHeader) { + if (auto *Decl = dyn_cast(&I)) { + NoAliasScopeDeclInstructions.push_back(Decl); + } else if (IntrinsicInst *II = dyn_cast(&I)) { + if (II->getIntrinsicID() == Intrinsic::noalias_decl) { + // Check usage validity: + bool UsedInsideHeader = false; + bool UsedOutsideHeaderInsideLoop = false; + for (User *U : II->users()) { + Instruction *UI = cast(U); + if (UI->getParent() == OrigHeader) { + UsedInsideHeader = true; + } else if (L->contains(UI)) { + UsedOutsideHeaderInsideLoop = true; + } else { + if (PHINode *PUI = dyn_cast(UI)) { + if (PUI->getNumIncomingValues() > 1) { + LLVM_DEBUG( + llvm::dbgs() + << "LoopRotation: NOT rotating - " << *II + << "\n used in PHI node " << *PUI + << ",\n in exit block with multiple entries.\n"); + return false; + } + } + ProvenanceNoAliasOrNoAliasToDisconnect.push_back(UI); + } + } + + if (UsedInsideHeader && UsedOutsideHeaderInsideLoop) { + LLVM_DEBUG(llvm::dbgs() + << "LoopRotation: NOT rotating - " << *II + << " used in header and other parts of the loop.\n" + " Rotation would reduced the llvm.noalias quality " + "too much.\n"); + return false; + } + + NoAliasDeclInstructions.push_back(II); + } + } + } + + // If we get here, we will do the rotate. + // First break the link between any llvm.noalias.decl and its outside-loop + // usage + for (Instruction *I : ProvenanceNoAliasOrNoAliasToDisconnect) { + unsigned OpN; + if (PHINode *PI = dyn_cast(I)) { + // can only happen when in the exit block -> single predecessor ! + assert(PI->getNumIncomingValues() == 1 && + "PHI node should have a single value"); + (void)PI; // Silence not-used warning in Release builds + OpN = 0; + } else { + IntrinsicInst *II = cast(I); + if (II->getIntrinsicID() == Intrinsic::provenance_noalias) { + OpN = Intrinsic::ProvenanceNoAliasNoAliasDeclArg; + } else if (II->getIntrinsicID() == Intrinsic::noalias) { + OpN = Intrinsic::NoAliasNoAliasDeclArg; + } else { + assert(II->getIntrinsicID() == Intrinsic::noalias_copy_guard); + OpN = Intrinsic::NoAliasCopyGuardNoAliasDeclArg; + } + } + + auto *PT = cast(I->getOperand(OpN)->getType()); + I->setOperand(OpN, ConstantPointerNull::get(PT)); + } + } while (I != E) { Instruction *Inst = &*I++; @@ -472,7 +547,9 @@ } } - if (!NoAliasDeclInstructions.empty()) { + if (!NoAliasDeclInstructions.empty() || + !NoAliasScopeDeclInstructions.empty()) { + // There are noalias scope declarations: // (general): // Original: OrigPre { OrigHeader NewHeader ... Latch } @@ -480,6 +557,8 @@ // // with D: llvm.experimental.noalias.scope.decl, // U: !noalias or !alias.scope depending on D + // or with D: llvm.noalias.decl, + // U: llvm.provenance.noalias depending on D // ... { D U1 U2 } can transform into: // (0) : ... { D U1 U2 } // no relevant rotation for this part // (1) : ... D' { U1 U2 D } // D is part of OrigHeader @@ -488,20 +567,41 @@ // We now want to transform: // (1) -> : ... D' { D U1 U2 D'' } // (2) -> : ... D' U1' { D U2 D'' U1'' } - // D: original llvm.experimental.noalias.scope.decl + // D: original llvm.experimental.noalias.scope.decl/llvm.noalias.decl // D', U1': duplicate with replaced scopes // D'', U1'': different duplicate with replaced scopes // This ensures a safe fallback to 'may_alias' introduced by the rotate, // as U1'' and U1' scopes will not be compatible wrt to the local restrict - // Clone the llvm.experimental.noalias.decl again for the NewHeader. + // Clone the llvm.experimental.noalias.decl/llvm.noalias.decl again for + // the NewHeader. + Instruction *NewHeaderInsertionPoint = &(*NewHeader->getFirstNonPHI()); - for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions) { + for (NoAliasScopeDeclInst *NAD : NoAliasScopeDeclInstructions) { LLVM_DEBUG(dbgs() << " Cloning llvm.experimental.noalias.scope.decl:" << *NAD << "\n"); Instruction *NewNAD = NAD->clone(); NewNAD->insertBefore(NewHeaderInsertionPoint); } + for (Instruction *NAD : NoAliasDeclInstructions) { + LLVM_DEBUG(llvm::dbgs() + << " Cloning llvm.noalias.decl:" << *NAD << "\n"); + Instruction *NewNAD = NAD->clone(); + //@ FIXME: NewNAD->insertBefore(NewHeaderInsertionPoint); + NewNAD->insertBefore(NAD); + + // remap dependencies in the OrigHeader block to NewNAD + NAD->replaceUsesInsideBlock(NewNAD, OrigHeader); + + // And move the original NAD to the NewHeader + NAD->moveBefore(NewHeaderInsertionPoint); + + // Now forget about the original NAD mapping + auto tmp = + ValueMap[NAD]; // use a local copy to avoid undefined behavior + ValueMap[NewNAD] = tmp; // this could trigger a reallocation. + ValueMap.erase(NAD); + } // Scopes must now be duplicated, once for OrigHeader and once for // OrigPreHeader'. @@ -509,25 +609,30 @@ auto &Context = NewHeader->getContext(); SmallVector NoAliasDeclScopes; - for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions) + for (auto *NAD : NoAliasScopeDeclInstructions) NoAliasDeclScopes.push_back(NAD->getScopeList()); + for (auto *NAD : NoAliasDeclInstructions) + NoAliasDeclScopes.push_back( + cast(cast( + NAD->getOperand(Intrinsic::NoAliasDeclScopeArg)) + ->getMetadata())); LLVM_DEBUG(dbgs() << " Updating OrigHeader scopes\n"); cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, {OrigHeader}, Context, "h.rot"); LLVM_DEBUG(OrigHeader->dump()); + // FIXME: originally we were updating only a part of the OrigPreHeader + // FIXME: for now, for easyness, we update the complete OrigPreHeader. + // FIXME: the comment below is not true any more ! // Keep the compile time impact low by only adapting the inserted block // of instructions in the OrigPreHeader. This might result in slightly // more aliasing between these instructions and those that were already // present, but it will be much faster when the original PreHeader is // large. - LLVM_DEBUG(dbgs() << " Updating part of OrigPreheader scopes\n"); - auto *FirstDecl = - cast(ValueMap[*NoAliasDeclInstructions.begin()]); - auto *LastInst = &OrigPreheader->back(); - cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, FirstDecl, LastInst, - Context, "pre.rot"); + LLVM_DEBUG(dbgs() << " Updating OrigPreheader scopes\n"); + cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, {OrigPreheader}, Context, + "pre.rot"); LLVM_DEBUG(OrigPreheader->dump()); LLVM_DEBUG(dbgs() << " Updated NewHeader:\n"); Index: llvm/lib/Transforms/Utils/LoopUnroll.cpp =================================================================== --- llvm/lib/Transforms/Utils/LoopUnroll.cpp +++ llvm/lib/Transforms/Utils/LoopUnroll.cpp @@ -61,6 +61,7 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopSimplify.h" #include "llvm/Transforms/Utils/LoopUtils.h" +#include "llvm/Transforms/Utils/NoAliasUtils.h" #include "llvm/Transforms/Utils/SimplifyIndVar.h" #include "llvm/Transforms/Utils/UnrollLoop.h" #include "llvm/Transforms/Utils/ValueMapper.h" @@ -514,10 +515,20 @@ SmallVector LoopLocalNoAliasDeclScopes; identifyNoAliasScopesToClone(L->getBlocks(), LoopLocalNoAliasDeclScopes); + if (!LoopLocalNoAliasDeclScopes.empty() && (ULO.Count > 1)) { + // We have loop local llvm.noalias.decl. If they are used by code that is + // considered to be outside the loop, the must go through the latch block. + // We duplicate the llvm.noalias.decl to the latch block, so that migrated + // code can still locally benefit from the noalias information. But it will + // get disconnected from the information inside the loop body itself. + llvm::cloneNoAliasDeclIntoExit(L); + } + // We place the unrolled iterations immediately after the original loop // latch. This is a reasonable default placement if we don't have block // frequencies, and if we do, well the layout will be adjusted later. auto BlockInsertPt = std::next(LatchBlock->getIterator()); + for (unsigned It = 1; It != ULO.Count; ++It) { SmallVector NewBlocks; SmallDenseMap NewLoops; @@ -605,15 +616,25 @@ AC->registerAssumption(II); { - // Identify what other metadata depends on the cloned version. After - // cloning, replace the metadata with the corrected version for both - // memory instructions and noalias intrinsics. + // Phase2: identify what other metadata depends on the cloned version + // Phase3: after cloning, replace the metadata with the corrected version + // for both memory instructions and noalias intrinsics std::string ext = (Twine("It") + Twine(It)).str(); cloneAndAdaptNoAliasScopes(LoopLocalNoAliasDeclScopes, NewBlocks, Header->getContext(), ext); } } + if (!LoopLocalNoAliasDeclScopes.empty() && (ULO.Count > 1)) { + // Also adapt the scopes of the first iteration to avoid any + // conflicts with instructions outside the loop using the + // scopes. Those have already been taken care of by + // duplicating the llvm.noalias.decl. + std::vector OldBlocks(BlockBegin, BlockEnd); + cloneAndAdaptNoAliasScopes(LoopLocalNoAliasDeclScopes, OldBlocks, + Header->getContext(), "It0"); + } + // Loop over the PHI nodes in the original block, setting incoming values. for (PHINode *PN : OrigPHINode) { if (CompletelyUnroll) { Index: llvm/lib/Transforms/Utils/NoAliasUtils.cpp =================================================================== --- /dev/null +++ llvm/lib/Transforms/Utils/NoAliasUtils.cpp @@ -0,0 +1,200 @@ +//===-- NoAliasUtils.cpp - NoAlias Utility functions ----------------------===// +// +// 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 common noalias metadatt and intrinsic utility functions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Utils/NoAliasUtils.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "noalias-utils" + +bool llvm::propagateAndConnectNoAliasDecl(Function *F) { + auto *UnknownFunctionScope = F->getMetadata("noalias"); + if (UnknownFunctionScope == nullptr) + return false; + + SmallVector InterestingNoalias; + SmallMapVector KnownAllocaNoAliasDecl; + + auto TrackIfIsUnknownFunctionScope = [&](IntrinsicInst *I, unsigned Index) { + auto V = I->getOperand(Index); + if (cast(V)->getMetadata() == UnknownFunctionScope) { + InterestingNoalias.push_back(I); + } + }; + + for (Instruction &I : llvm::instructions(*F)) { + if (IntrinsicInst *II = dyn_cast(&I)) { + switch (II->getIntrinsicID()) { + case Intrinsic::noalias: { + TrackIfIsUnknownFunctionScope(II, Intrinsic::NoAliasScopeArg); + break; + } + case Intrinsic::provenance_noalias: { + TrackIfIsUnknownFunctionScope(II, Intrinsic::ProvenanceNoAliasScopeArg); + break; + } + case Intrinsic::noalias_copy_guard: { + TrackIfIsUnknownFunctionScope(II, Intrinsic::NoAliasCopyGuardScopeArg); + break; + } + case Intrinsic::noalias_decl: { + auto *depAlloca = dyn_cast(II->getOperand(0)); + if (depAlloca) { + KnownAllocaNoAliasDecl[depAlloca] = II; + } + break; + } + default: + break; + } + } + } + + if (KnownAllocaNoAliasDecl.empty() || InterestingNoalias.empty()) + return false; + + bool Changed = false; + for (auto *II : InterestingNoalias) { + SmallVector UO; + unsigned Index = + (II->getIntrinsicID() == Intrinsic::noalias + ? 0 + : (II->getIntrinsicID() == Intrinsic::provenance_noalias ? 1 : 2)); + const int IdentifyPArg[] = {Intrinsic::NoAliasIdentifyPArg, + Intrinsic::ProvenanceNoAliasIdentifyPArg, + Intrinsic::NoAliasCopyGuardIdentifyPBaseObject}; + const int ScopeArg[] = {Intrinsic::NoAliasScopeArg, + Intrinsic::ProvenanceNoAliasScopeArg, + Intrinsic::NoAliasCopyGuardScopeArg}; + const int NoAliasDeclArg[] = {Intrinsic::NoAliasNoAliasDeclArg, + Intrinsic::ProvenanceNoAliasNoAliasDeclArg, + Intrinsic::NoAliasCopyGuardNoAliasDeclArg}; + const int ObjIdArg[] = {Intrinsic::NoAliasIdentifyPObjIdArg, + Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg, -1}; + + llvm::getUnderlyingObjects(II->getOperand(IdentifyPArg[Index]), UO); + if (UO.size() != 1) { + // Multiple objects possible - It would be nice to propagate, but we do + // not do it yet. That is ok as the unknown function scope assumes more + // aliasing. + LLVM_DEBUG(llvm::dbgs() + << "WARNING: no llvm.noalias.decl reconnect accross " + "PHI/select - YET (" + << UO.size() << " underlying objects)\n"); + continue; + } + + if (auto *UA = dyn_cast(UO[0])) { + auto it = KnownAllocaNoAliasDecl.find(UA); + if (it != KnownAllocaNoAliasDecl.end()) { + Instruction *Decl = it->second; + // found a simple matching declaration - propagate + II->setOperand(ScopeArg[Index], + Decl->getOperand(Intrinsic::NoAliasDeclScopeArg)); + II->setOperand(NoAliasDeclArg[Index], Decl); + + auto ObjIdIndex = ObjIdArg[Index]; + if (ObjIdIndex != -1) { + II->setOperand(ObjIdIndex, + Decl->getOperand(Intrinsic::NoAliasDeclObjIdArg)); + } + Changed = true; + } else if (UnknownFunctionScope && isa(UA)) { + if (cast(II->getOperand(ScopeArg[Index])) + ->getMetadata() == UnknownFunctionScope) { + // we have an alloca, but no llvm.noalias.decl and we have unknown + // function scope This is an indication of a temporary that (through a + // pointer or reference to a restrict pointer) introduces restrict. + // - the unknown scope is too broad for these cases + // - conceptually, the scope should be the lifetime of the local, but + // we don't have that information + // - the real restrictness should have been brought in through the + // 'depends on' relationship + // -> so we fall back on the 'depends on' and remove the restrictness + // information at this level. + LLVM_DEBUG( + llvm::dbgs() + << "- Temporary noalias object (without llvm.noalias.decl) " + "detected. Ignore restrictness: " + << *II << "\n"); + II->replaceAllUsesWith(II->getOperand(0)); + II->eraseFromParent(); + Changed = true; + } + } + } else { +#if !defined(NDEBUG) + if (isa(UO[0]) || isa(UO[0])) { + // Multiple objects possible - It would be nice to propagate, but we do + // not do it yet. That is ok as the unknown function scope assumes more + // aliasing. + LLVM_DEBUG(llvm::dbgs() + << "WARNING: no llvm.noalias.decl reconnect accross " + "PHI/select - YET: " + << *UO[0] << "\n"); + } +#endif + } + } + return Changed; +} + +void llvm::cloneNoAliasDeclIntoExit(Loop *L) { + // We have loop local llvm.noalias.decl. If they are used by code that is + // considered to be outside the loop, the must go through the latch block. + // We duplicate the llvm.noalias.decl to the latch block, so that migrated + // code can still locally benefit from the noalias information. But it will + // get disconnected from the information inside the loop body itself. + SmallVector UniqueExitBlocks; + L->getUniqueExitBlocks(UniqueExitBlocks); + for (auto *EB : UniqueExitBlocks) { + SmallVector, 6> ClonedNoAlias; + + for (auto &PN : EB->phis()) { + Value *V = PN.getIncomingValue(0); + while (true) { + if (IntrinsicInst *II = dyn_cast(V)) { + if (II->getIntrinsicID() == Intrinsic::noalias_decl) { + ClonedNoAlias.emplace_back(II->clone(), &PN); + } + } else if (PHINode *PN2 = dyn_cast(V)) { + if (PN2->getNumIncomingValues() == 1) { + // look through phi ( phi (.. ) ) in case of nested loops + V = PN2->getIncomingValue(0); + continue; + } + } + break; + } + } + + auto IP = EB->getFirstInsertionPt(); + for (auto P : ClonedNoAlias) { + EB->getInstList().insert(IP, P.first); + } + for (auto P : ClonedNoAlias) { + P.second->replaceAllUsesWith(P.first); + } + } +} Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp =================================================================== --- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -25,7 +25,6 @@ #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/IteratedDominanceFrontier.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" @@ -35,6 +34,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" @@ -45,6 +45,7 @@ #include "llvm/IR/Type.h" #include "llvm/IR/User.h" #include "llvm/Support/Casting.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" #include #include @@ -61,36 +62,248 @@ STATISTIC(NumDeadAlloca, "Number of dead alloca's removed"); STATISTIC(NumPHIInsert, "Number of PHI nodes inserted"); -bool llvm::isAllocaPromotable(const AllocaInst *AI) { +class PromotableChecker { +public: + bool isChecker() const { return true; } + + bool check(bool c) { return c; } + void trackRemovable(const Instruction *I) {} + void trackDroppableUse(const Use *U) {} + void trackOperandToZero(const Instruction *I, int operand) {} + void trackNoAliasDecl(const IntrinsicInst *II) {} + + void trackRemovableOrDroppableUses(const Instruction *I) {} + + bool wasPHINodeHandled(PHINode* P) { + return !HandledPhis.insert(P).second; + } + +public: + SmallPtrSet HandledPhis; +}; + +class PromotableTracker { +public: + bool isChecker() const { return false; } + + bool check(bool c) { + assert(!c && "PromotableTracker::check failed"); + return false; + } + void trackRemovable(Instruction *I) { + // FIXME: Performance Warning: linear search - might become slow (?) + if (std::find(Removables.begin(), Removables.end(), I) == Removables.end()) + Removables.push_back(I); + } + void trackDroppableUse(Use *U) { DroppableUses.push_back(U); } + void trackOperandToZero(Instruction *I, int operand) { + ZeroOperands.emplace_back(I, operand); + } + void trackNoAliasDecl(IntrinsicInst *II) { NoAliasDecls.push_back(II); } + + void trackRemovableOrDroppableUses(Instruction *I) { + for (auto &U_ : I->uses()) { + if (U_.getUser()->isDroppable()) + trackDroppableUse(&U_); + else + trackRemovable(cast(U_.getUser())); + } + } + + bool wasPHINodeHandled(PHINode* P) { + return !HandledPhis.insert(P).second; + } + +public: + SmallVector Removables; + SmallVector DroppableUses; + SmallVector, 4> ZeroOperands; + SmallVector NoAliasDecls; + SmallPtrSet HandledPhis; +}; + +// Return true if the only usage of this pointer is as identifyP argument for +// llvm.noalias or llvm.provenance.noalias (either direct or recursive) +// Look through bitcast, getelementptr, llvm.noalias, llvm.provenance.noalias + +template +bool onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(Value *V, PT &pt); + +template +bool isAndOnlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(IntrinsicInst *II, + unsigned OpNo, + PT &pt) { + if (II->getIntrinsicID() == Intrinsic::provenance_noalias) { + if (OpNo == 0) { + if (!onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(II, pt)) + return false; + pt.trackRemovable(II); + } else if (OpNo == Intrinsic::ProvenanceNoAliasIdentifyPArg) { + pt.trackOperandToZero(II, OpNo); + } else if (OpNo == Intrinsic::ProvenanceNoAliasIdentifyPProvenanceArg) { + pt.trackOperandToZero(II, OpNo); + } else { + assert(false && "Unexpected llvm.provenance.noalias dependency"); + } + return true; + } else if (II->getIntrinsicID() == Intrinsic::noalias) { + if (OpNo == 0) { + if (!onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(II, pt)) + return false; + pt.trackRemovable(II); + } else if (OpNo == Intrinsic::NoAliasIdentifyPArg) { + pt.trackOperandToZero(II, OpNo); + } else { + assert(false && "Unexpected llvm.provenance.noalias dependency"); + } + return true; + } + + return false; +} + +template +bool onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(Value *V, PT &pt) { + for (Use &U_ : V->uses()) { + // Remember: either 'return false' or 'continue'. 'return true' is never + // valid inside this loop. + unsigned OpNo = U_.getOperandNo(); + User *U = U_.getUser(); + if (IntrinsicInst *II = dyn_cast(U)) { + if (isAndOnlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(II, OpNo, pt)) + continue; + return false; + } else if (BitCastInst *BCI = dyn_cast(U)) { + if (!onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(BCI, pt)) + return false; + pt.trackRemovable(BCI); + } else if (GetElementPtrInst *GEPI = dyn_cast(U)) { + if (!onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(GEPI, pt)) + return false; + pt.trackRemovable(GEPI); + } else if (AddrSpaceCastInst *ASCI = dyn_cast(U)) { + if (!onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(ASCI, pt)) + return false; + pt.trackRemovable(ASCI); + } else if (LoadInst *LI = dyn_cast(U)) { + // Ok if this is the PtrProvenance operand + if (OpNo != LI->getNoaliasProvenanceOperandIndex()) + return false; + pt.trackOperandToZero(LI, OpNo); + } else if (StoreInst *SI = dyn_cast(U)) { + if (OpNo != SI->getNoaliasProvenanceOperandIndex()) + return false; + pt.trackOperandToZero(SI, OpNo); + } else if (SelectInst *SI = dyn_cast(U)) { + if (OpNo == 0) + return false; + pt.trackOperandToZero(SI, OpNo); + if (pt.isChecker()) + if (!onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(SI, pt)) + return false; + } else if (PHINode *PN = dyn_cast(U)) { + pt.trackOperandToZero(PN, OpNo); + if (pt.wasPHINodeHandled(PN)) + continue; + if (pt.isChecker()) + if (!onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(PN, pt)) + return false; + } else { + return false; + } + } + return true; +} + +template bool trackAllocaPromotable(AllocaInst *AI, PT &pt) { // Only allow direct and non-volatile loads and stores... - for (const User *U : AI->users()) { - if (const LoadInst *LI = dyn_cast(U)) { + for (Use &U_ : AI->uses()) { + unsigned OpNo = U_.getOperandNo(); + User *U = U_.getUser(); + + if (LoadInst *LI = dyn_cast(U)) { // Note that atomic loads can be transformed; atomic semantics do // not have any meaning for a local alloca. - if (LI->isVolatile()) + if (pt.check(LI->isVolatile())) return false; - } else if (const StoreInst *SI = dyn_cast(U)) { - if (SI->getValueOperand() == AI || - SI->getValueOperand()->getType() != AI->getAllocatedType()) + if (OpNo == LI->getNoaliasProvenanceOperandIndex()) { + // Load will be removed. Disconnect provenance.noalias dependency + pt.trackOperandToZero(LI, OpNo); + } + } else if (StoreInst *SI = dyn_cast(U)) { + if (pt.check(OpNo == 0)) return false; // Don't allow a store OF the AI, only INTO the AI. + if (pt.check(SI->getValueOperand()->getType() != AI->getAllocatedType())) + return false; // Don't allow a store OF a different type into the AI // Note that atomic stores can be transformed; atomic semantics do // not have any meaning for a local alloca. - if (SI->isVolatile()) + if (pt.check(SI->isVolatile())) return false; - } else if (const IntrinsicInst *II = dyn_cast(U)) { - if (!II->isLifetimeStartOrEnd() && !II->isDroppable()) + if (OpNo == SI->getNoaliasProvenanceOperandIndex()) { + // Store will be removed. Disconnect provenance.noalias dependency + pt.trackOperandToZero(SI, OpNo); + } + } else if (IntrinsicInst *II = dyn_cast(U)) { + switch (II->getIntrinsicID()) { + case Intrinsic::lifetime_start: + case Intrinsic::lifetime_end: + pt.trackRemovable(II); + break; + case Intrinsic::noalias_decl: + pt.trackNoAliasDecl(II); + break; + case Intrinsic::noalias: + case Intrinsic::provenance_noalias: + if (!isAndOnlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(II, OpNo, + pt)) + return false; + break; + default: + if (II->isDroppable()) { + pt.trackDroppableUse(&U_); + break; + } return false; - } else if (const BitCastInst *BCI = dyn_cast(U)) { - if (!onlyUsedByLifetimeMarkersOrDroppableInsts(BCI)) + } + } else if (BitCastInst *BCI = dyn_cast(U)) { + if (onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(BCI, pt)) { + pt.trackRemovable(BCI); + continue; + } + if (pt.check(!onlyUsedByLifetimeMarkersOrDroppableInsts(BCI))) return false; - } else if (const GetElementPtrInst *GEPI = dyn_cast(U)) { - if (!GEPI->hasAllZeroIndices()) + + pt.trackRemovableOrDroppableUses(BCI); + pt.trackRemovable(BCI); + } else if (AddrSpaceCastInst *ACI = dyn_cast(U)) { + if (onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(ACI, pt)) { + pt.trackRemovable(ACI); + continue; + } + if (pt.check(!onlyUsedByLifetimeMarkersOrDroppableInsts(ACI))) return false; - if (!onlyUsedByLifetimeMarkersOrDroppableInsts(GEPI)) + + pt.trackRemovableOrDroppableUses(ACI); + pt.trackRemovable(ACI); + } else if (GetElementPtrInst *GEPI = dyn_cast(U)) { + if (onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(GEPI, pt)) { + pt.trackRemovable(GEPI); + continue; + } + if (pt.check(!GEPI->hasAllZeroIndices())) return false; - } else if (const AddrSpaceCastInst *ASCI = dyn_cast(U)) { - if (!onlyUsedByLifetimeMarkers(ASCI)) + if (pt.check(!onlyUsedByLifetimeMarkersOrDroppableInsts(GEPI))) return false; + + pt.trackRemovableOrDroppableUses(GEPI); + pt.trackRemovable(GEPI); + } else if (AddrSpaceCastInst *ASCI = dyn_cast(U)) { + if (onlyUsedByNoaliasOrProvenanceNoAliasIdentifyPArg(ASCI, pt)) { + pt.trackRemovable(ASCI); + continue; + } + + return false; } else { return false; } @@ -99,6 +312,11 @@ return true; } +bool llvm::isAllocaPromotable(const AllocaInst *AI) { + PromotableChecker pc; + return trackAllocaPromotable(const_cast(AI), pc); +} + namespace { struct AllocaInfo { @@ -312,34 +530,196 @@ static void removeIntrinsicUsers(AllocaInst *AI) { // Knowing that this alloca is promotable, we know that it's safe to kill all - // instructions except for load and store. + // instructions except for load and store and noalias intrinsics. - for (Use &U : llvm::make_early_inc_range(AI->uses())) { - Instruction *I = cast(U.getUser()); - if (isa(I) || isa(I)) - continue; + // Track the possible intrinsics. If we do not have a noalias.decl or we do + // not have an unknown function scope, no extra modificiations are needed. If + // both are there, we need to propagate the MetadataValue from the declaration + // to those intrinsics that are using the unknown scope. + PromotableTracker pt; - // Drop the use of AI in droppable instructions. - if (I->isDroppable()) { - I->dropDroppableUse(U); - continue; - } + if (!trackAllocaPromotable(AI, pt)) { + assert(false && "trackAllocaPromotable not consistent"); + } - if (!I->getType()->isVoidTy()) { - // The only users of this bitcast/GEP instruction are lifetime intrinsics. - // Follow the use/def chain to erase them now instead of leaving it for - // dead code elimination later. - for (Use &UU : llvm::make_early_inc_range(I->uses())) { - Instruction *Inst = cast(UU.getUser()); + // Propagate NoaliasDecl + MDNode *NoAliasUnknownScopeMD = + AI->getParent()->getParent()->getMetadata("noalias"); + Instruction *NoAliasDecl = nullptr; + if (pt.NoAliasDecls.size() == 1) + NoAliasDecl = pt.NoAliasDecls[0]; + + if (NoAliasUnknownScopeMD) { + if (NoAliasDecl) { + LLVM_DEBUG(llvm::dbgs() + << "- Propagating " << *NoAliasDecl << " scope to:\n"); + auto NoAliasDeclScope = + NoAliasDecl->getOperand(Intrinsic::NoAliasDeclScopeArg); + for (auto PairIO : pt.ZeroOperands) { + Instruction *I = PairIO.first; + auto OpNo = PairIO.second; + (void)OpNo; // Silence not used warning in Release builds. + if (IntrinsicInst *II = dyn_cast(I)) { + auto ID = II->getIntrinsicID(); + if (ID == Intrinsic::noalias || ID == Intrinsic::provenance_noalias) { + // If we get here, we can assume the identifyP or its provenance + // are dependencies + assert( + (ID == Intrinsic::noalias) + ? (OpNo == Intrinsic::NoAliasIdentifyPArg) + : (OpNo == Intrinsic::ProvenanceNoAliasIdentifyPArg || + OpNo == + Intrinsic::ProvenanceNoAliasIdentifyPProvenanceArg)); + unsigned ScopeArg = (ID == Intrinsic::noalias + ? Intrinsic::NoAliasScopeArg + : Intrinsic::ProvenanceNoAliasScopeArg); + unsigned DeclArg = + (ID == Intrinsic::noalias + ? Intrinsic::NoAliasNoAliasDeclArg + : Intrinsic::ProvenanceNoAliasNoAliasDeclArg); + MetadataAsValue *MV = + cast(I->getOperand(ScopeArg)); + if (NoAliasUnknownScopeMD == MV->getMetadata()) { + // Propagate the declaration scope + // Note: splitting already took care of updating the ObjId + LLVM_DEBUG(llvm::dbgs() << "-- " << *I << "\n"); + II->setOperand(ScopeArg, NoAliasDeclScope); + + // also update the noalias declaration + II->setOperand(DeclArg, NoAliasDecl); + } + } + } + } + } else if (pt.NoAliasDecls.empty()) { + for (auto PairIO : pt.ZeroOperands) { + Instruction *I = PairIO.first; + auto OpNo = PairIO.second; + (void)OpNo; // Silence not used warning in Release builds. + if (IntrinsicInst *II = dyn_cast(I)) { + auto ID = II->getIntrinsicID(); + if (ID == Intrinsic::noalias || ID == Intrinsic::provenance_noalias) { + // If we get here, we can assume the identifyP or its provenance + // are dependencies + assert( + (ID == Intrinsic::noalias) + ? (OpNo == Intrinsic::NoAliasIdentifyPArg) + : (OpNo == Intrinsic::ProvenanceNoAliasIdentifyPArg || + OpNo == + Intrinsic::ProvenanceNoAliasIdentifyPProvenanceArg)); + unsigned ScopeArg = (ID == Intrinsic::noalias + ? Intrinsic::NoAliasScopeArg + : Intrinsic::ProvenanceNoAliasScopeArg); + MetadataAsValue *MV = + cast(I->getOperand(ScopeArg)); + if (NoAliasUnknownScopeMD == MV->getMetadata()) { + // Propagate a more or less unique id + LLVM_DEBUG(llvm::dbgs() + << "-- No llvm.noalias.decl, looking through: " << *I + << "\n"); + II->replaceAllUsesWith(II->getOperand(0)); + } + } + } + } + } + } - // Drop the use of I in droppable instructions. - if (Inst->isDroppable()) { - Inst->dropDroppableUse(UU); + if (NoAliasDecl) { + // Check if we need to split up llvm.noalias.decl with unique ObjId's + // This is needed to differentiate restrict pointers, once the alloca is + // removed. NOTE: we might as well have depended on 'constant propagation of + // null' and work with a 'constant pointer' + // for IdentifyP. Not sure what mechanism would be the best. + const DataLayout &DL = AI->getParent()->getModule()->getDataLayout(); + std::map ObjId2NoAliasDecl; + + auto BaseObjId = cast(NoAliasDecl->getOperand( + Intrinsic::NoAliasDeclObjIdArg)) + ->getZExtValue(); + ObjId2NoAliasDecl[BaseObjId] = NoAliasDecl; + + for (auto PairIO : pt.ZeroOperands) { + IntrinsicInst *II = dyn_cast(PairIO.first); + if (II && ((II->getIntrinsicID() == Intrinsic::noalias) || + (II->getIntrinsicID() == Intrinsic::provenance_noalias))) { + auto OpNo = PairIO.second; + unsigned IdentifyPArg = (II->getIntrinsicID() == Intrinsic::noalias) + ? Intrinsic::NoAliasIdentifyPArg + : Intrinsic::ProvenanceNoAliasIdentifyPArg; + unsigned ObjIdArg = (II->getIntrinsicID() == Intrinsic::noalias) + ? Intrinsic::NoAliasIdentifyPObjIdArg + : Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg; + unsigned NoAliasDeclArg = + (II->getIntrinsicID() == Intrinsic::noalias) + ? Intrinsic::NoAliasNoAliasDeclArg + : Intrinsic::ProvenanceNoAliasNoAliasDeclArg; + + if ((unsigned)OpNo != IdentifyPArg) continue; + + auto CurrentObjId = + cast(II->getOperand(ObjIdArg))->getZExtValue(); + + assert(CurrentObjId == BaseObjId && + "Initial object id difference detected."); + + APInt PPointerOffset(DL.getPointerSizeInBits(), 0ull); + assert(AI == II->getOperand(IdentifyPArg) + ->stripAndAccumulateInBoundsConstantOffsets( + DL, PPointerOffset) && + "hmm.. expected stripped P to map to alloca"); + if (!PPointerOffset.isNullValue()) { + CurrentObjId += PPointerOffset.getZExtValue(); + auto &NewNoAliasDecl = ObjId2NoAliasDecl[CurrentObjId]; + if (NewNoAliasDecl == nullptr) { + LLVM_DEBUG(llvm::dbgs() + << "Creating llvm.noalias.decl for IdentifyPObjId " + << CurrentObjId << "\n"); + IRBuilder NoAliasDeclBuilder(NoAliasDecl); + NewNoAliasDecl = NoAliasDeclBuilder.CreateNoAliasDeclaration( + ConstantPointerNull::get(cast(AI->getType())), + CurrentObjId, + NoAliasDecl->getOperand(Intrinsic::NoAliasDeclScopeArg)); + LLVM_DEBUG(llvm::dbgs() << "- " << *NewNoAliasDecl << "\n"); + } + II->setOperand(NoAliasDeclArg, NewNoAliasDecl); + II->setOperand(ObjIdArg, + ConstantInt::get(II->getOperand(ObjIdArg)->getType(), + CurrentObjId)); + LLVM_DEBUG(llvm::dbgs() + << "Remapping noalias.decl dependency: " << *II << "\n"); } - Inst->eraseFromParent(); } } + } + + // set args to zero + for (auto II : pt.NoAliasDecls) { + LLVM_DEBUG(llvm::dbgs() << "Zeoring noalias.decl dep: " << *II << "\n"); + assert(II->getIntrinsicID() == Intrinsic::noalias_decl); + II->setOperand(Intrinsic::NoAliasDeclAllocaArg, + ConstantPointerNull::get(cast(AI->getType()))); + } + for (auto PairIO : pt.ZeroOperands) { + Instruction *I = PairIO.first; + auto OpNo = PairIO.second; + LLVM_DEBUG(llvm::dbgs() + << "Zeroing operand " << OpNo << " of " << *I << "\n"); + I->setOperand(OpNo, ConstantPointerNull::get( + cast(I->getOperand(OpNo)->getType()))); + } + + // Drop droppables + for (auto U : pt.DroppableUses) { + LLVM_DEBUG(llvm::dbgs() << "Dropping use from " << *U->getUser() << "\n"); + assert(U->getUser()->isDroppable()); + U->getUser()->dropDroppableUse(*U); + } + + // remove + for (auto I : pt.Removables) { + LLVM_DEBUG(llvm::dbgs() << "Removing " << *I << "\n"); I->eraseFromParent(); } } @@ -363,8 +743,12 @@ // Clear out UsingBlocks. We will reconstruct it here if needed. Info.UsingBlocks.clear(); - for (User *U : make_early_inc_range(AI->users())) { - Instruction *UserInst = cast(U); + for (auto UI = AI->user_begin(), E = AI->user_end(); + UI != E;) { // FIXME: make_early_inc_range ? + Instruction *UserInst = cast(*UI++); + // load/store can have a provenance + if ((UI != E) && (*UI == UserInst)) + ++UI; if (UserInst == OnlyStore) continue; LoadInst *LI = cast(UserInst); @@ -477,8 +861,11 @@ // Walk all of the loads from this alloca, replacing them with the nearest // store above them, if any. - for (User *U : make_early_inc_range(AI->users())) { - LoadInst *LI = dyn_cast(U); + for (auto UI = AI->user_begin(), E = AI->user_end(); UI != E;) { + LoadInst *LI = dyn_cast(*UI++); + // load/store can have a provenance + if ((UI != E) && (*UI == LI)) + ++UI; if (!LI) continue; Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1520,6 +1520,7 @@ LLVMContext::MD_dereferenceable, LLVMContext::MD_dereferenceable_or_null, LLVMContext::MD_mem_parallel_loop_access, + LLVMContext::MD_noalias, LLVMContext::MD_access_group, LLVMContext::MD_preserve_access_index}; combineMetadata(I1, I2, KnownIDs, true); @@ -3487,7 +3488,13 @@ /*BranchWeights=*/nullptr, DTU); QB.SetInsertPoint(T); StoreInst *SI = cast(QB.CreateStore(QPHI, Address)); - SI->setAAMetadata(PStore->getAAMetadata().merge(QStore->getAAMetadata())); + AAMDNodes AAMD = PStore->getAAMetadata().merge(QStore->getAAMetadata()); + SI->setAAMetadata(AAMD); + auto CommonPtrProvenance = + mergePtrProvenance(PStore->getOptionalPtrProvenance(), + QStore->getOptionalPtrProvenance()); + if (CommonPtrProvenance) + SI->setNoaliasProvenanceOperand(CommonPtrProvenance.getValue()); // Choose the minimum alignment. If we could prove both stores execute, we // could use biggest one. In this case, though, we only know that one of the // stores executes. And we don't know it's safe to take the alignment from a Index: llvm/lib/Transforms/Utils/ValueMapper.cpp =================================================================== --- llvm/lib/Transforms/Utils/ValueMapper.cpp +++ llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -518,6 +518,8 @@ return getVM()[V] = UndefValue::get(NewTy); if (isa(C)) return getVM()[V] = ConstantAggregateZero::get(NewTy); + if (isa(C)) + return getVM()[V] = UnknownProvenance::get(cast(NewTy)); assert(isa(C)); return getVM()[V] = ConstantPointerNull::get(cast(NewTy)); } Index: llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp +++ llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp @@ -272,9 +272,10 @@ // The real propagateMetadata expects a SmallVector, but we deal in // vectors of Instructions. -static void propagateMetadata(Instruction *I, ArrayRef IL) { +static void propagateMetadata(Instruction *I, ArrayRef IL, + bool RemoveNoAlias) { SmallVector VL(IL.begin(), IL.end()); - propagateMetadata(I, VL); + propagateMetadata(I, VL, RemoveNoAlias); } // Vectorizer Implementation @@ -1153,11 +1154,14 @@ } } + bool HasProvenance = llvm::any_of(Chain, [](const auto &I) { + return cast(I)->hasNoaliasProvenanceOperand(); + }); StoreInst *SI = Builder.CreateAlignedStore( Vec, Builder.CreateBitCast(S0->getPointerOperand(), VecTy->getPointerTo(AS)), Alignment); - propagateMetadata(SI, Chain); + propagateMetadata(SI, Chain, HasProvenance); eraseInstructions(Chain); ++NumVectorInstructions; @@ -1283,11 +1287,14 @@ std::tie(First, Last) = getBoundaryInstrs(Chain); Builder.SetInsertPoint(&*First); + bool HasProvenance = llvm::any_of(Chain, [](const auto &I) { + return cast(I)->hasNoaliasProvenanceOperand(); + }); Value *Bitcast = Builder.CreateBitCast(L0->getPointerOperand(), VecTy->getPointerTo(AS)); LoadInst *LI = Builder.CreateAlignedLoad(VecTy, Bitcast, MaybeAlign(Alignment)); - propagateMetadata(LI, Chain); + propagateMetadata(LI, Chain, HasProvenance); if (VecLoadTy) { SmallVector InstrsToErase; Index: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -1175,7 +1175,13 @@ void InnerLoopVectorizer::addMetadata(Instruction *To, Instruction *From) { - propagateMetadata(To, From); + bool HasProvenance = true; + if (auto *SI = dyn_cast(From)) { + HasProvenance = SI->hasNoaliasProvenanceOperand(); + } else if (auto *LI = dyn_cast(From)) { + HasProvenance = LI->hasNoaliasProvenanceOperand(); + } + propagateMetadata(To, From, HasProvenance); addNewMetadata(To, From); } @@ -3906,11 +3912,6 @@ if (VF.isScalar()) return ScalarCallCost; - // Compute corresponding vector type for return value and arguments. - Type *RetTy = ToVectorTy(ScalarRetTy, VF); - for (Type *ScalarTy : ScalarTys) - Tys.push_back(ToVectorTy(ScalarTy, VF)); - // Compute costs of unpacking argument values for the scalar calls and // packing the return values to a vector. InstructionCost ScalarizationCost = getScalarizationOverhead(CI, VF); @@ -3927,6 +3928,11 @@ if (!TLI || CI->isNoBuiltin() || !VecFunc) return Cost; + // Compute corresponding vector type for return value and arguments. + Type *RetTy = ToVectorTy(ScalarRetTy, VF); + for (Type *ScalarTy : ScalarTys) + Tys.push_back(ToVectorTy(ScalarTy, VF)); + // If the corresponding vector cost is cheaper, return its cost. InstructionCost VectorCallCost = TTI.getCallInstrCost(nullptr, RetTy, Tys, TTI::TCK_RecipThroughput); @@ -8948,7 +8954,8 @@ if (ID && (ID == Intrinsic::assume || ID == Intrinsic::lifetime_end || ID == Intrinsic::lifetime_start || ID == Intrinsic::sideeffect || ID == Intrinsic::pseudoprobe || - ID == Intrinsic::experimental_noalias_scope_decl)) + ID == Intrinsic::experimental_noalias_scope_decl || + ID == Intrinsic::noalias || ID == Intrinsic::provenance_noalias)) return nullptr; auto willWiden = [&](ElementCount VF) -> bool { Index: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp =================================================================== --- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -1740,6 +1740,8 @@ auto *I0 = cast(Scalars[0]); Operands.resize(I0->getNumOperands()); unsigned NumLanes = Scalars.size(); + assert(!(isa(I0) || isa(I0)) && + "Use setLoadStoreOperandsInOrder"); for (unsigned OpIdx = 0, NumOperands = I0->getNumOperands(); OpIdx != NumOperands; ++OpIdx) { Operands[OpIdx].resize(NumLanes); @@ -1758,6 +1760,53 @@ reorderScalars(Operand, Mask); } + /// Set the operands of this bundle of load or store instructions in their + /// original order. + void setLoadStoreOperandsInOrder() { + assert(Operands.empty() && "Already initialized?"); + auto *I0 = cast(Scalars[0]); + assert((isa(I0) || isa(I0)) && + "Expect a load or store instruction"); + unsigned NumBaseOperands = isa(I0) ? 1 : 2; + + // Check if any instruction has a ptr_provenance + bool HasProvenance = llvm::any_of(Scalars, [&](auto *V) { + return cast(V)->getNumOperands() != NumBaseOperands; + }); + + Operands.resize(NumBaseOperands + HasProvenance); + unsigned NumLanes = Scalars.size(); + for (unsigned OpIdx = 0; OpIdx != NumBaseOperands; ++OpIdx) { + auto &Op = Operands[OpIdx]; + Op.resize(NumLanes); + for (unsigned Lane = 0; Lane != NumLanes; ++Lane) { + auto *I = cast(Scalars[Lane]); + assert(((I->getNumOperands() == NumBaseOperands) || + (I->getNumOperands() == NumBaseOperands + 1)) && + "Expected same number of operands (ignoring the " + "ptr_provenance"); + Op[Lane] = I->getOperand(OpIdx); + } + } + + if (HasProvenance) { + // At least one instruction has a ptr_provenance. + // Keep track of the dependencies brought in by it. Later on we will + // omit the noalias information. + auto &Op = Operands[NumBaseOperands]; + Op.resize(NumLanes); + for (unsigned Lane = 0; Lane != NumLanes; ++Lane) { + auto *I = cast(Scalars[Lane]); + if (I->getNumOperands() != NumBaseOperands) { + Op[Lane] = I->getOperand(NumBaseOperands); + } else { + Op[Lane] = + UndefValue::get(I->getOperand(NumBaseOperands - 1)->getType()); + } + } + } + } + /// \returns the \p OpIdx operand of this TreeEntry. ValueList &getOperand(unsigned OpIdx) { assert(OpIdx < Operands.size() && "Off bounds"); @@ -1996,7 +2045,7 @@ /// Maps a specific scalar to its tree entry. SmallDenseMap ScalarToTreeEntry; - /// Maps a value to the proposed vectorizable size. + /// Maps a value to the proposed vectorizable size. SmallDenseMap InstrElementSize; /// A list of scalars that we found that we need to keep as scalars. @@ -2317,6 +2366,7 @@ auto *In = TE->getMainOp(); assert(In && (isa(In) || isa(In) || + isa(In) || isa(In) || In->getNumOperands() == TE->getNumOperands()) && "Missed TreeEntry operands?"); (void)In; // fake use to avoid build failure when assertions disabled @@ -3663,13 +3713,13 @@ ReuseShuffleIndicies, CurrentOrder); LLVM_DEBUG(dbgs() << "SLP: added a vector of jumbled loads.\n"); } - TE->setOperandsInOrder(); + TE->setLoadStoreOperandsInOrder(); break; case LoadsState::ScatterVectorize: // Vectorizing non-consecutive loads with `llvm.masked.gather`. TE = newTreeEntry(VL, TreeEntry::ScatterVectorize, Bundle, S, UserTreeIdx, ReuseShuffleIndicies); - TE->setOperandsInOrder(); + TE->setLoadStoreOperandsInOrder(); buildTree_rec(PointerOps, Depth + 1, {TE, 0}); LLVM_DEBUG(dbgs() << "SLP: added a vector of non-consecutive loads.\n"); break; @@ -3964,7 +4014,7 @@ // Original stores are consecutive and does not require reordering. TreeEntry *TE = newTreeEntry(VL, Bundle /*vectorized*/, S, UserTreeIdx, ReuseShuffleIndicies); - TE->setOperandsInOrder(); + TE->setLoadStoreOperandsInOrder(); buildTree_rec(Operands, Depth + 1, {TE, 0}); LLVM_DEBUG(dbgs() << "SLP: added a vector of stores.\n"); } else { @@ -3972,7 +4022,7 @@ TreeEntry *TE = newTreeEntry(VL, Bundle /*vectorized*/, S, UserTreeIdx, ReuseShuffleIndicies, CurrentOrder); - TE->setOperandsInOrder(); + TE->setLoadStoreOperandsInOrder(); buildTree_rec(Operands, Depth + 1, {TE, 0}); LLVM_DEBUG(dbgs() << "SLP: added a vector of jumbled stores.\n"); } @@ -6032,7 +6082,7 @@ auto *PtrTy = PointerType::get(VecTy, LI->getPointerAddressSpace()); Value *Ptr = Builder.CreateBitCast(LI->getOperand(0), PtrTy); LoadInst *V = Builder.CreateAlignedLoad(VecTy, Ptr, LI->getAlign()); - Value *NewV = propagateMetadata(V, E->Scalars); + Value *NewV = propagateMetadata(V, E->Scalars, true); ShuffleBuilder.addInversedMask(E->ReorderIndices); ShuffleBuilder.addMask(E->ReuseShuffleIndices); NewV = ShuffleBuilder.finalize(NewV); @@ -6275,7 +6325,8 @@ commonAlignment(CommonAlignment, cast(V)->getAlign()); NewLI = Builder.CreateMaskedGather(VecTy, VecPtr, CommonAlignment); } - Value *V = propagateMetadata(NewLI, E->Scalars); + Value *V = + propagateMetadata(NewLI, E->Scalars, (E->getNumOperands() == 2)); ShuffleBuilder.addInversedMask(E->ReorderIndices); ShuffleBuilder.addMask(E->ReuseShuffleIndices); @@ -6310,7 +6361,7 @@ ExternalUser(ScalarPtr, cast(VecPtr), FoundLane)); } - Value *V = propagateMetadata(ST, E->Scalars); + Value *V = propagateMetadata(ST, E->Scalars, (E->getNumOperands() == 3)); E->VectorizedValue = V; ++NumVectorInstructions; Index: llvm/test/Analysis/BasicAA/noalias-intr.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/BasicAA/noalias-intr.ll @@ -0,0 +1,143 @@ +; RUN: opt < %s -basic-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; Function Attrs: nounwind +define void @test01() #0 { +entry: + %_pA = alloca i32, align 4 + %_pB = alloca i32, align 4 + %t1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %t3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !5) + %t5 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %t1, i32** null, i32 0, metadata !2), !tbaa !7, !noalias !11 + store i32 42, i32* %t5, align 4, !tbaa !12, !noalias !11 + %t7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pB, i8* %t3, i32** null, i32 0, metadata !5), !tbaa !7, !noalias !11 + store i32 43, i32* %t7, align 4, !tbaa !12, !noalias !11 + ret void +} +; CHECK-LABEL: Function: test01: +; CHECK: NoAlias: i32* %t5, i32* %t7 + +; Function Attrs: nounwind +define void @test02() #0 { +entry: + %_pA = alloca i32, align 4 + %_pB = alloca i32, align 4 + %t1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %t3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !5) + %t5 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %t1, i32** null, i32 0, metadata !2), !tbaa !7, !noalias !11 + store i32 42, i32* %t5, align 4, !tbaa !12, !noalias !11 + %t7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %t3, i32** null, i32 0, metadata !5), !tbaa !7, !noalias !11 + store i32 43, i32* %t7, align 4, !tbaa !12, !noalias !11 + ret void +} +; CHECK-LABEL: Function: test02: +; CHECK: MustAlias: i32* %t5, i32* %t7 + + +; Function Attrs: nounwind +define void @test11() #0 { +entry: + %_pA = alloca i32, align 4 + %_pB = alloca i32, align 4 + %t1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %t3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !5) + %t5 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %t1, i32** null, i32** undef, i32 0, metadata !2), !tbaa !7, !noalias !11 + %.guard1 = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %t5) + store i32 42, i32* %.guard1, align 4, !tbaa !12, !noalias !11 + %.guard2 = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pB, i32* %t5) + store i32 43, i32* %.guard2, align 4, !tbaa !12, !noalias !11 + ret void +} +; CHECK-LABEL: Function: test11: +; CHECK: NoAlias: i32* %.guard1, i32* %.guard2 + +; Function Attrs: nounwind +define void @test12() #0 { +entry: + %_pA = alloca i32, align 4 + %_pB = alloca i32, align 4 + %t1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %t3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !5) + %t5 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %t1, i32** null, i32** undef, i32 0, metadata !2), !tbaa !7, !noalias !11 + %.guard1 = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %t5) + store i32 42, i32* %.guard1, align 4, !tbaa !12, !noalias !11 + %.guard2 = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %t5) + store i32 43, i32* %.guard2, align 4, !tbaa !12, !noalias !11 + ret void +} +; CHECK-LABEL: Function: test12: +; CHECK: MustAlias: i32* %.guard1, i32* %.guard2 + +; Function Attrs: nounwind +define void @test21() #0 { +entry: + %_pA = alloca i32, align 4 + %_pB = alloca i32, align 4 + %t1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %t3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !5) + %.guard1 = call i32* @llvm.noalias.copy.guard.p0i32.p0i8(i32* %_pA, i8* %t1, metadata !14, metadata !2) + store i32 42, i32* %.guard1, align 4, !tbaa !12, !noalias !11 + %.guard2 = call i32* @llvm.noalias.copy.guard.p0i32.p0i8(i32* %_pB, i8* %t3, metadata !14, metadata !5) + store i32 43, i32* %.guard2, align 4, !tbaa !12, !noalias !11 + ret void +} +; CHECK-LABEL: Function: test21: +; CHECK: NoAlias: i32* %.guard1, i32* %.guard2 + +; Function Attrs: nounwind +define void @test22() #0 { +entry: + %_pA = alloca i32, align 4 + %_pB = alloca i32, align 4 + %t1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %t3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !5) + %.guard1 = call i32* @llvm.noalias.copy.guard.p0i32.p0i8(i32* %_pA, i8* %t1, metadata !14, metadata !2) + store i32 42, i32* %.guard1, align 4, !tbaa !12, !noalias !11 + %.guard2 = call i32* @llvm.noalias.copy.guard.p0i32.p0i8(i32* %_pA, i8* %t3, metadata !14, metadata !5) + store i32 43, i32* %.guard2, align 4, !tbaa !12, !noalias !11 + ret void +} +; CHECK-LABEL: Function: test22: +; CHECK: MustAlias: i32* %.guard1, i32* %.guard2 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) #2 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #3 + +; Function Attrs: nounwind readnone +declare i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32*, i32*) #4 + +; Function Attrs: nounwind readnone +declare i32* @llvm.noalias.copy.guard.p0i32.p0i8(i32*, i8*, metadata, metadata) #4 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { argmemonly nounwind speculatable } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind readnone } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test01: _pA"} +!4 = distinct !{!4, !"test01"} +!5 = !{!6} +!6 = distinct !{!6, !4, !"test01: _pB"} +!7 = !{!8, !8, i64 0, i64 4} +!8 = !{!9, i64 4, !"any pointer"} +!9 = !{!10, i64 1, !"omnipotent char"} +!10 = !{!"Simple C/C++ TBAA"} +!11 = !{!3, !6} +!12 = !{!13, !13, i64 0, i64 4} +!13 = !{!9, i64 4, !"int"} +!14 = !{!15} +!15 = !{i64 -1, i64 0} Index: llvm/test/Analysis/ScopedNoAliasAA/basic-domains.ll =================================================================== --- llvm/test/Analysis/ScopedNoAliasAA/basic-domains.ll +++ llvm/test/Analysis/ScopedNoAliasAA/basic-domains.ll @@ -52,4 +52,3 @@ ; CHECK: NoAlias: store float %1, float* %arrayidx.i2, align 4, !noalias !6 <-> store float %0, float* %arrayidx.i, align 4, !noalias !6 ; CHECK: NoAlias: store float %2, float* %arrayidx.i3, align 4, !noalias !7 <-> store float %0, float* %arrayidx.i, align 4, !noalias !6 ; CHECK: NoAlias: store float %2, float* %arrayidx.i3, align 4, !noalias !7 <-> store float %1, float* %arrayidx.i2, align 4, !noalias !6 - Index: llvm/test/Analysis/ScopedNoAliasAA/basic2.ll =================================================================== --- llvm/test/Analysis/ScopedNoAliasAA/basic2.ll +++ llvm/test/Analysis/ScopedNoAliasAA/basic2.ll @@ -38,4 +38,3 @@ !3 = !{!3, !2, !"some other scope"} !4 = !{!1} !5 = !{!3} - Index: llvm/test/Analysis/ScopedNoAliasAA/noalias-calls.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias-calls.ll @@ -0,0 +1,62 @@ +; RUN: opt < %s -basic-aa -scoped-noalias-aa -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) #1 + +; Function Attrs: nounwind +declare void @hey() #1 + +; Function Attrs: nounwind uwtable +define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 { +entry: + %l.i = alloca i8, i32 512, align 1 + %prov.a = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %a, i8* null, i8** null, i8** null, i32 0, metadata !0) #0 + %prov.b = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %c, i8* null, i8** null, i8** null, i32 0, metadata !3) #0 + %a.guard = call i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8* %a, i8* %prov.a) + %c.guard = call i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8* %c, i8* %prov.b) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %b, i64 16, i1 false) #1, !noalias !5 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 + call void @hey() #1, !noalias !5 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %l.i, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 + ret void +} + +; CHECK-LABEL: Function: foo: +; CHECK: Just Ref: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %b, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: Just Mod: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %b, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: Just Ref: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %b, i64 16, i1 false) #1, !noalias !5 <-> call void @hey() #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %b, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %l.i, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: Just Mod: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %b, i64 16, i1 false) #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: Just Mod: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @hey() #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %l.i, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: Just Mod: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %b, i64 16, i1 false) #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @hey() #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %l.i, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: Just Mod: call void @hey() #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %b, i64 16, i1 false) #1, !noalias !5 +; CHECK: Both ModRef: call void @hey() #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: NoModRef: call void @hey() #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: NoModRef: call void @hey() #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %l.i, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %l.i, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %b, i64 16, i1 false) #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %l.i, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %b, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %l.i, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a.guard, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 +; CHECK: NoModRef: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %l.i, i8* %c.guard, i64 16, i1 false) #1, !noalias !5 <-> call void @hey() #1, !noalias !5 + +declare i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8*, i8*, i8**, i8**, i32, metadata) nounwind readnone speculatable +declare i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8*, i8*) nounwind readnone + +attributes #0 = { argmemonly nounwind } +attributes #1 = { nounwind } +attributes #2 = { nounwind uwtable } + + +!0 = !{!1} +!1 = distinct !{!1, !2, !"hello: %a"} +!2 = distinct !{!2, !"hello"} +!3 = !{!4} +!4 = distinct !{!4, !2, !"hello: %c"} +!5 = !{!1, !4} Index: llvm/test/Analysis/ScopedNoAliasAA/noalias-dup-scope.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias-dup-scope.ll @@ -0,0 +1,161 @@ +; RUN: opt < %s -basic-aa -domtree -scoped-noalias-aa -aa-eval -loops -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s -check-prefix=WITHDT +; Note: The -loops above can be anything that requires the domtree, and is +; necessary to work around a pass-manager bug. + +target datalayout = "E-m:e-i64:64-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@a = common global i32* null, align 8 +@r = common global i32 0, align 4 +@a2 = common global i32* null, align 8 + +; Function Attrs: nounwind +define i32* @foo() #0 { +entry: + %0 = load i32*, i32** @a, align 8, !tbaa !1, !noalias !5 + %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %0, i8* null, i32** @a, i32** null, i32 0, metadata !5) #0 + %2 = tail call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %0, i32* %1) #0 + ret i32* %1 +} + +; Function Attrs: nounwind +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #0 + +; Function Attrs: nounwind +declare i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32*, i32*) #0 + +; Function Attrs: nounwind +define i32* @foo1(i32 signext %b) #0 { +entry: + %tobool = icmp eq i32 %b, 0 + br i1 %tobool, label %if.else, label %if.then + +if.then: ; preds = %entry + %0 = load i32*, i32** @a, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !8 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %0, i8* null, i32** @a, i32** null, i32 0, metadata !12) #0 + %2 = load i32, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !13, !noalias !8 + %3 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !13, !noalias !8 + %add = add nsw i32 %3, %2 + store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !13, !noalias !8 + %guard.1 = tail call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %0, i32* %1) #0 + tail call void @ex1(i32* %guard.1) #0, !noalias !8 + %incdec.ptr = getelementptr inbounds i32, i32* %0, i64 1 + %4 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %0, i8* null, i32** @a, i32** null, i32 0, metadata !12) #0 + %5 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !13, !noalias !8 + store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !13, !noalias !8 + %guard.5 = tail call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %incdec.ptr, i32* %4) #0 + tail call void @ex1(i32* %guard.5) #0, !noalias !8 + %idx.ext = sext i32 %b to i64 + %add.ptr = getelementptr inbounds i32, i32* %incdec.ptr, i64 %idx.ext + %6 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %0, i8* null, i32** @a, i32** null, i32 0, metadata !12) #0 + %7 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !13, !noalias !8 + store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !13, !noalias !8 + %guard.6 = tail call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %add.ptr, i32* %6) #0 + tail call void @ex1(i32* %guard.6) #0, !noalias !8 + %8 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !8 + %9 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %8, i8* null, i32** @a2, i32** null, i32 0, metadata !15) #0 + %10 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !13, !noalias !8 + store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !13, !noalias !8 + %guard.9 = tail call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %8, i32* %9) #0 + tail call void @ex1(i32* %guard.9) #0, !noalias !8 + br label %if.end + +if.else: ; preds = %entry + %11 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !12 + %12 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %11, i8* null, i32** @a2, i32** null, i32 0, metadata !12) #0 + %13 = load i32, i32* %11, ptr_provenance i32* %12, align 4, !tbaa !13, !noalias !12 + %14 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !13, !noalias !12 + %add1 = add nsw i32 %14, %13 + store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !13, !noalias !12 + br label %if.end + +if.end: ; preds = %if.else, %if.then + %x.0 = phi i32* [ %0, %if.then ], [ %11, %if.else ] + %prov.x.0 = phi i32* [ %6, %if.then ], [ %12, %if.else ] + %x.0.guard = tail call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %x.0, i32* %prov.x.0) #0 + ret i32* %x.0.guard +} + +; WITHDT: NoAlias: %0 = load i32*, i32** @a, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %0 = load i32*, i32** @a, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %0 = load i32*, i32** @a, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %0 = load i32*, i32** @a, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %0 = load i32*, i32** @a, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: NoAlias: %2 = load i32, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !10, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %2 = load i32, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !10, !noalias !5 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: MayAlias: %2 = load i32, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !10, !noalias !5 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %2 = load i32, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !10, !noalias !5 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %2 = load i32, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !10, !noalias !5 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: MustAlias: %3 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %3 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %3 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %3 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: MustAlias: %3 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: MustAlias: %5 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %5 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %5 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %5 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: MustAlias: %5 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: MustAlias: %7 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %7 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %7 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %7 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: MustAlias: %7 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: NoAlias: %8 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %8 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %8 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %8 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %8 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !5 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: MustAlias: %10 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %10 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %10 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %10 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: MustAlias: %10 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: NoAlias: %11 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !9 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %11 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !9 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %11 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !9 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: MayAlias: %11 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !9 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %11 = load i32*, i32** @a2, ptr_provenance i32** null, align 8, !tbaa !1, !noalias !9 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: NoAlias: %13 = load i32, i32* %11, ptr_provenance i32* %12, align 4, !tbaa !10, !noalias !9 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %13 = load i32, i32* %11, ptr_provenance i32* %12, align 4, !tbaa !10, !noalias !9 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %13 = load i32, i32* %11, ptr_provenance i32* %12, align 4, !tbaa !10, !noalias !9 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: MayAlias: %13 = load i32, i32* %11, ptr_provenance i32* %12, align 4, !tbaa !10, !noalias !9 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %13 = load i32, i32* %11, ptr_provenance i32* %12, align 4, !tbaa !10, !noalias !9 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: MustAlias: %14 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %14 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: %14 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: MayAlias: %14 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 +; WITHDT: MustAlias: %14 = load i32, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 <-> store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 +; WITHDT: NoAlias: store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: MustAlias: store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 <-> store i32 %add, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 <-> store i32 %5, i32* %incdec.ptr, ptr_provenance i32* %4, align 4, !tbaa !10, !noalias !5 +; WITHDT: NoAlias: store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 <-> store i32 %7, i32* %add.ptr, ptr_provenance i32* %6, align 4, !tbaa !10, !noalias !5 +; WITHDT: MayAlias: store i32 %add1, i32* @r, ptr_provenance i32* null, align 4, !tbaa !10, !noalias !9 <-> store i32 %10, i32* %8, ptr_provenance i32* %9, align 4, !tbaa !10, !noalias !5 + +declare void @ex1(i32*) + +attributes #0 = { nounwind } + +!llvm.ident = !{!0} + +!0 = !{!"clang"} +!1 = !{!2, !2, i64 0} +!2 = !{!"any pointer", !3, i64 0} +!3 = !{!"omnipotent char", !4, i64 0} +!4 = !{!"Simple C/C++ TBAA"} +!5 = !{!6} +!6 = distinct !{!6, !7, !"foo: x"} +!7 = distinct !{!7, !"foo"} +!8 = !{!9, !11} +!9 = distinct !{!9, !10, !"foo1: x2"} +!10 = distinct !{!10, !"foo1"} +!11 = distinct !{!11, !10, !"foo1: x"} +!12 = !{!11} +!13 = !{!14, !14, i64 0} +!14 = !{!"int", !3, i64 0} +!15 = !{!9} Index: llvm/test/Analysis/ScopedNoAliasAA/noalias.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias.ll @@ -0,0 +1,66 @@ +; RUN: opt < %s -basic-aa -scoped-noalias-aa -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind uwtable +define void @foo(float* nocapture %a, float* nocapture readonly %c, i64 %i0, i64 %i1) #0 { +entry: + %prov.a = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %a, i8* null, float** null, float** null, i32 0, metadata !0) #1 + %0 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !0 + %arrayidx.i = getelementptr inbounds float, float* %a, i64 %i0 + store float %0, float* %arrayidx.i, ptr_provenance float* %prov.a, align 4, !noalias !0 + %1 = load float, float* %c, align 4 + %arrayidx = getelementptr inbounds float, float* %a, i64 %i1 + store float %1, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !0 + ret void +} + +; CHECK-LABEL: Function: foo: +; CHECK: NoAlias: %0 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !0 <-> store float %0, float* %arrayidx.i, ptr_provenance float* %prov.a, align 4, !noalias !0 +; CHECK: MayAlias: %0 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !0 <-> store float %1, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !0 +; CHECK: MayAlias: %1 = load float, float* %c, align 4 <-> store float %0, float* %arrayidx.i, ptr_provenance float* %prov.a, align 4, !noalias !0 +; CHECK: MayAlias: %1 = load float, float* %c, align 4 <-> store float %1, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !0 +; CHECK: NoAlias: store float %1, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !0 <-> store float %0, float* %arrayidx.i, ptr_provenance float* %prov.a, align 4, !noalias !0 + + +; Function Attrs: nounwind uwtable +define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c, i64 %i0, i64 %i1) #0 { +entry: + %0 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %a, i8* null, float** null, float** null, i32 0, metadata !3) #1 + %1 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %b, i8* null, float** null, float** null, i32 0, metadata !6) #1 + %2 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !8 + %arrayidx.i = getelementptr inbounds float, float* %a, i64 5 + store float %2, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !8 + %arrayidx1.i = getelementptr inbounds float, float* %b, i64 %i0 + store float %2, float* %arrayidx1.i, ptr_provenance float* %1, align 4, !noalias !8 + %3 = load float, float* %c, align 4 + %arrayidx = getelementptr inbounds float, float* %a, i64 %i1 + store float %3, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !8 + ret void +} + +; CHECK-LABEL: Function: foo2: +; CHECK: NoAlias: %2 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !5 <-> store float %2, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !5 +; CHECK: NoAlias: %2 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !5 <-> store float %2, float* %arrayidx1.i, ptr_provenance float* %1, align 4, !noalias !5 +; CHECK: MayAlias: %2 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !5 <-> store float %3, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !5 +; CHECK: MayAlias: %3 = load float, float* %c, align 4 <-> store float %2, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !5 +; CHECK: MayAlias: %3 = load float, float* %c, align 4 <-> store float %2, float* %arrayidx1.i, ptr_provenance float* %1, align 4, !noalias !5 +; CHECK: MayAlias: %3 = load float, float* %c, align 4 <-> store float %3, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !5 +; CHECK: NoAlias: store float %2, float* %arrayidx1.i, ptr_provenance float* %1, align 4, !noalias !5 <-> store float %2, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !5 +; CHECK: NoAlias: store float %3, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !5 <-> store float %2, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !5 +; CHECK: NoAlias: store float %3, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !5 <-> store float %2, float* %arrayidx1.i, ptr_provenance float* %1, align 4, !noalias !5 + +declare float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float*, i8*, float**, float**, i32, metadata ) nounwind + +attributes #0 = { nounwind uwtable } +attributes #1 = { nounwind } + +!0 = !{!1} +!1 = distinct !{!1, !2, !"hello: %a"} +!2 = distinct !{!2, !"hello"} +!3 = !{!4} +!4 = distinct !{!4, !5, !"hello2: %a"} +!5 = distinct !{!5, !"hello2"} +!6 = !{!7} +!7 = distinct !{!7, !5, !"hello2: %b"} +!8 = !{!4, !7} Index: llvm/test/Analysis/ScopedNoAliasAA/noalias2.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias2.ll @@ -0,0 +1,113 @@ +; RUN: opt < %s -basic-aa -scoped-noalias-aa -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind uwtable +define void @foo(float* noalias nocapture %a, float* noalias nocapture readonly %c) #0 { +entry: + %0 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %a, i8* null, float** null, float** null, i32 0, metadata !0) #1 + %1 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %c, i8* null, float** null, float** null, i32 0, metadata !3) #1 + %2 = load float, float* %c, ptr_provenance float* %1, align 4, !noalias !5 + %arrayidx.i = getelementptr inbounds float, float* %a, i64 5 + store float %2, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !5 + %3 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !5 + %arrayidx = getelementptr inbounds float, float* %a, i64 7 + store float %3, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !5 + ret void +} + +; CHECK-LABEL: Function: foo: +; CHECK: NoAlias: %2 = load float, float* %c, ptr_provenance float* %1, align 4, !noalias !5 <-> store float %2, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !5 +; CHECK: NoAlias: %2 = load float, float* %c, ptr_provenance float* %1, align 4, !noalias !5 <-> store float %3, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !5 +; CHECK: NoAlias: %3 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !5 <-> store float %2, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !5 +; CHECK: NoAlias: %3 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !5 <-> store float %3, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !5 +; CHECK: NoAlias: store float %3, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !5 <-> store float %2, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !5 + +; Function Attrs: nounwind uwtable +define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 { +entry: + %0 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %a, i8* null, float** null, float** null, i32 0, metadata !6) #1 + %1 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %c, i8* null, float** null, float** null, i32 0, metadata !9) #1 + %2 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %0, i8* null, float** null, float** null, i32 0, metadata !11) #1, !noalias !14 + %3 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %1, i8* null, float** null, float** null, i32 0, metadata !15) #1, !noalias !14 + %4 = load float, float* %c, ptr_provenance float* %3, align 4, !noalias !17 + %arrayidx.i.i = getelementptr inbounds float, float* %a, i64 5 + store float %4, float* %arrayidx.i.i, ptr_provenance float* %2, align 4, !noalias !17 + %5 = load float, float* %c, ptr_provenance float* %1, align 4, !noalias !14 + %arrayidx.i = getelementptr inbounds float, float* %a, i64 7 + store float %5, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !14 + %6 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %a, i8* null, float** null, float** null, i32 0, metadata !18) #1 + %7 = call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %b, i8* null, float** null, float** null, i32 0, metadata !21) #1 + %8 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !23 + %arrayidx.i1 = getelementptr inbounds float, float* %a, i64 6 + store float %8, float* %arrayidx.i1, ptr_provenance float* %6, align 4, !noalias !23 + %arrayidx1.i = getelementptr inbounds float, float* %b, i64 8 + store float %8, float* %arrayidx1.i, ptr_provenance float* %7, align 4, !noalias !23 + ; %9 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !23 + %9 = load float, float* %c, align 4 + %arrayidx = getelementptr inbounds float, float* %a, i64 7 + store float %9, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !23 + ret void +} + +; CHECK-LABEL: Function: foo2: +; CHECK: NoAlias: %4 = load float, float* %c, ptr_provenance float* %3, align 4, !noalias !11 <-> store float %4, float* %arrayidx.i.i, ptr_provenance float* %2, align 4, !noalias !11 +; CHECK: NoAlias: %4 = load float, float* %c, ptr_provenance float* %3, align 4, !noalias !11 <-> store float %5, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !8 +; CHECK: MayAlias: %4 = load float, float* %c, ptr_provenance float* %3, align 4, !noalias !11 <-> store float %8, float* %arrayidx.i1, ptr_provenance float* %6, align 4, !noalias !17 +; CHECK: MayAlias: %4 = load float, float* %c, ptr_provenance float* %3, align 4, !noalias !11 <-> store float %8, float* %arrayidx1.i, ptr_provenance float* %7, align 4, !noalias !17 +; CHECK: MayAlias: %4 = load float, float* %c, ptr_provenance float* %3, align 4, !noalias !11 <-> store float %9, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !17 +; CHECK: NoAlias: %5 = load float, float* %c, ptr_provenance float* %1, align 4, !noalias !8 <-> store float %4, float* %arrayidx.i.i, ptr_provenance float* %2, align 4, !noalias !11 +; CHECK: NoAlias: %5 = load float, float* %c, ptr_provenance float* %1, align 4, !noalias !8 <-> store float %5, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !8 +; CHECK: MayAlias: %5 = load float, float* %c, ptr_provenance float* %1, align 4, !noalias !8 <-> store float %8, float* %arrayidx.i1, ptr_provenance float* %6, align 4, !noalias !17 +; CHECK: MayAlias: %5 = load float, float* %c, ptr_provenance float* %1, align 4, !noalias !8 <-> store float %8, float* %arrayidx1.i, ptr_provenance float* %7, align 4, !noalias !17 +; CHECK: MayAlias: %5 = load float, float* %c, ptr_provenance float* %1, align 4, !noalias !8 <-> store float %9, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !17 +; CHECK: MayAlias: %8 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !17 <-> store float %4, float* %arrayidx.i.i, ptr_provenance float* %2, align 4, !noalias !11 +; CHECK: MayAlias: %8 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !17 <-> store float %5, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !8 +; CHECK: NoAlias: %8 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !17 <-> store float %8, float* %arrayidx.i1, ptr_provenance float* %6, align 4, !noalias !17 +; CHECK: NoAlias: %8 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !17 <-> store float %8, float* %arrayidx1.i, ptr_provenance float* %7, align 4, !noalias !17 +; CHECK: MayAlias: %8 = load float, float* %c, ptr_provenance float* null, align 4, !noalias !17 <-> store float %9, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !17 +; CHECK: MayAlias: %9 = load float, float* %c, align 4 <-> store float %4, float* %arrayidx.i.i, ptr_provenance float* %2, align 4, !noalias !11 +; CHECK: MayAlias: %9 = load float, float* %c, align 4 <-> store float %5, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !8 +; CHECK: MayAlias: %9 = load float, float* %c, align 4 <-> store float %8, float* %arrayidx.i1, ptr_provenance float* %6, align 4, !noalias !17 +; CHECK: MayAlias: %9 = load float, float* %c, align 4 <-> store float %8, float* %arrayidx1.i, ptr_provenance float* %7, align 4, !noalias !17 +; CHECK: MayAlias: %9 = load float, float* %c, align 4 <-> store float %9, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !17 +; CHECK: NoAlias: store float %5, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !8 <-> store float %4, float* %arrayidx.i.i, ptr_provenance float* %2, align 4, !noalias !11 +; CHECK: NoAlias: store float %8, float* %arrayidx.i1, ptr_provenance float* %6, align 4, !noalias !17 <-> store float %4, float* %arrayidx.i.i, ptr_provenance float* %2, align 4, !noalias !11 +; CHECK: NoAlias: store float %8, float* %arrayidx.i1, ptr_provenance float* %6, align 4, !noalias !17 <-> store float %5, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !8 +; CHECK: MayAlias: store float %8, float* %arrayidx1.i, ptr_provenance float* %7, align 4, !noalias !17 <-> store float %4, float* %arrayidx.i.i, ptr_provenance float* %2, align 4, !noalias !11 +; CHECK: MayAlias: store float %8, float* %arrayidx1.i, ptr_provenance float* %7, align 4, !noalias !17 <-> store float %5, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !8 +; CHECK: NoAlias: store float %8, float* %arrayidx1.i, ptr_provenance float* %7, align 4, !noalias !17 <-> store float %8, float* %arrayidx.i1, ptr_provenance float* %6, align 4, !noalias !17 +; CHECK: NoAlias: store float %9, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !17 <-> store float %4, float* %arrayidx.i.i, ptr_provenance float* %2, align 4, !noalias !11 +; CHECK: MustAlias: store float %9, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !17 <-> store float %5, float* %arrayidx.i, ptr_provenance float* %0, align 4, !noalias !8 +; CHECK: NoAlias: store float %9, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !17 <-> store float %8, float* %arrayidx.i1, ptr_provenance float* %6, align 4, !noalias !17 +; CHECK: NoAlias: store float %9, float* %arrayidx, ptr_provenance float* null, align 4, !noalias !17 <-> store float %8, float* %arrayidx1.i, ptr_provenance float* %7, align 4, !noalias !17 + +declare float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float*, i8*, float**, float**, i32, metadata ) nounwind + +attributes #0 = { nounwind uwtable } +attributes #1 = { nounwind } + +!0 = !{!1} +!1 = distinct !{!1, !2, !"hello: %a"} +!2 = distinct !{!2, !"hello"} +!3 = !{!4} +!4 = distinct !{!4, !2, !"hello: %c"} +!5 = !{!1, !4} +!6 = !{!7} +!7 = distinct !{!7, !8, !"foo: %a"} +!8 = distinct !{!8, !"foo"} +!9 = !{!10} +!10 = distinct !{!10, !8, !"foo: %c"} +!11 = !{!12} +!12 = distinct !{!12, !13, !"hello: %a"} +!13 = distinct !{!13, !"hello"} +!14 = !{!7, !10} +!15 = !{!16} +!16 = distinct !{!16, !13, !"hello: %c"} +!17 = !{!12, !16, !7, !10} +!18 = !{!19} +!19 = distinct !{!19, !20, !"hello2: %a"} +!20 = distinct !{!20, !"hello2"} +!21 = !{!22} +!22 = distinct !{!22, !20, !"hello2: %b"} +!23 = !{!19, !22} Index: llvm/test/Analysis/ScopedNoAliasAA/noalias_basics.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias_basics.ll @@ -0,0 +1,142 @@ +; RUN: opt < %s -basic-aa -scoped-noalias-aa -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nofree norecurse nounwind uwtable writeonly +define dso_local void @test_p_p(i32* nocapture %_pA, i32* nocapture %_pB) local_unnamed_addr #0 { +entry: + store i32 42, i32* %_pA, align 4, !tbaa !2 + store i32 99, i32* %_pB, align 4, !tbaa !2 + ret void +} +; CHECK-LABEL: Function: test_p_p: +; CHECK: MayAlias: store i32 99, i32* %_pB, align 4, !tbaa !2 <-> store i32 42, i32* %_pA, align 4, !tbaa !2 + +; Function Attrs: nounwind uwtable +define dso_local void @test_rp_p(i32* nocapture %_pA, i32* nocapture %_pB) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !6) + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !6), !tbaa !9, !noalias !6 + store i32 42, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !2, !noalias !6 + store i32 99, i32* %_pB, ptr_provenance i32* undef, align 4, !tbaa !2, !noalias !6 + ret void +} +; CHECK-LABEL: Function: test_rp_p: +; CHECK: NoAlias: store i32 99, i32* %_pB, ptr_provenance i32* undef, align 4, !tbaa !9, !noalias !2 <-> store i32 42, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #2 + +; Function Attrs: nounwind uwtable +define dso_local void @test_rp_rp_00(i32* nocapture %_pA, i32* nocapture %_pB) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !14) + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !11), !tbaa !9, !noalias !16 + store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !2, !noalias !16 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* %1, i32** null, i32** undef, i32 0, metadata !14), !tbaa !9, !noalias !16 + store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !2, !noalias !16 + ret void +} +; CHECK-LABEL: Function: test_rp_rp_00: +; CHECK: NoAlias: store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !12, !noalias !11 <-> store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !12, !noalias !11 + +; Now test variants: {objectP, objectID, Scope } +; NOTE: in the following tests, the Scope information is recycled from previous tests + +; Same info -> MayAlias +; Function Attrs: nounwind uwtable +define dso_local void @test_rp_rp_01(i32* nocapture %_pA, i32* nocapture %_pB) local_unnamed_addr #1 { +entry: + %a.p = alloca i32*, align 8 + %b.p = alloca i32*, align 8 + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** %a.p, i32 0, metadata !11) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** %b.p, i32 0, metadata !11) + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* null, i32** %a.p, i32** undef, i32 0, metadata !11), !tbaa !9, !noalias !16 + store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !2, !noalias !16 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* null, i32** %a.p, i32** undef, i32 0, metadata !11), !tbaa !9, !noalias !16 + store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !2, !noalias !16 + ret void +} +; CHECK-LABEL: Function: test_rp_rp_01: +; CHECK: MayAlias: store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !11, !noalias !9 <-> store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !11, !noalias !9 + +; Variants with different info -> NoAlias + +; Function Attrs: nounwind uwtable +define dso_local void @test_rp_rp_02(i32* nocapture %_pA, i32* nocapture %_pB) local_unnamed_addr #1 { +entry: + %a.p = alloca i32*, align 8 + %b.p = alloca i32*, align 8 + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** %a.p, i32 0, metadata !11) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** %b.p, i32 0, metadata !11) + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* null, i32** %a.p, i32** undef, i32 0, metadata !11), !tbaa !9, !noalias !16 + store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !2, !noalias !16 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* null, i32** %b.p, i32** undef, i32 0, metadata !11), !tbaa !9, !noalias !16 + store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !2, !noalias !16 + ret void +} +; CHECK-LABEL: Function: test_rp_rp_02: +; CHECK: NoAlias: store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !11, !noalias !9 <-> store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !11, !noalias !9 + +; Function Attrs: nounwind uwtable +define dso_local void @test_rp_rp_03(i32* nocapture %_pA, i32* nocapture %_pB) local_unnamed_addr #1 { +entry: + %a.p = alloca i32*, align 8 + %b.p = alloca i32*, align 8 + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** %a.p, i32 0, metadata !11) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** %b.p, i32 0, metadata !11) + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* null, i32** %a.p, i32** undef, i32 0, metadata !11), !tbaa !9, !noalias !16 + store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !2, !noalias !16 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* null, i32** %a.p, i32** undef, i32 1, metadata !11), !tbaa !9, !noalias !16 + store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !2, !noalias !16 + ret void +} +; CHECK-LABEL: Function: test_rp_rp_03: +; CHECK: NoAlias: store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !11, !noalias !9 <-> store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !11, !noalias !9 + +; Function Attrs: nounwind uwtable +define dso_local void @test_rp_rp_04(i32* nocapture %_pA, i32* nocapture %_pB) local_unnamed_addr #1 { +entry: + %a.p = alloca i32*, align 8 + %b.p = alloca i32*, align 8 + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** %a.p, i32 0, metadata !11) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** %b.p, i32 0, metadata !11) + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* null, i32** %a.p, i32** undef, i32 0, metadata !11), !tbaa !9, !noalias !16 + store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !2, !noalias !16 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* null, i32** %a.p, i32** undef, i32 0, metadata !14), !tbaa !9, !noalias !16 + store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !2, !noalias !16 + ret void +} +; CHECK-LABEL: Function: test_rp_rp_04: +; CHECK: NoAlias: store i32 99, i32* %_pB, ptr_provenance i32* %3, align 4, !tbaa !11, !noalias !9 <-> store i32 42, i32* %_pA, ptr_provenance i32* %2, align 4, !tbaa !11, !noalias !9 + + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #3 + +attributes #0 = { nofree norecurse nounwind uwtable writeonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { argmemonly nounwind } +attributes #3 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3, !3, i64 0} +!3 = !{!"int", !4, i64 0} +!4 = !{!"omnipotent char", !5, i64 0} +!5 = !{!"Simple C/C++ TBAA"} +!6 = !{!7} +!7 = distinct !{!7, !8, !"test_rp_p: pA"} +!8 = distinct !{!8, !"test_rp_p"} +!9 = !{!10, !10, i64 0} +!10 = !{!"any pointer", !4, i64 0} +!11 = !{!12} +!12 = distinct !{!12, !13, !"test_rp_rp: pA"} +!13 = distinct !{!13, !"test_rp_rp"} +!14 = !{!15} +!15 = distinct !{!15, !13, !"test_rp_rp: pB"} +!16 = !{!12, !15} Index: llvm/test/Analysis/ScopedNoAliasAA/noalias_member.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias_member.ll @@ -0,0 +1,64 @@ +; RUN: opt < %s -basic-aa -scoped-noalias-aa -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.FOO = type { i32*, i32* } + +; Function Attrs: nofree nounwind +define dso_local void @test_prp0_prp1(i32** nocapture %_pA) local_unnamed_addr #0 !noalias !2 { +entry: + %0 = load i32*, i32** %_pA, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %0, i8* null, i32** %_pA, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + %arrayidx1 = getelementptr inbounds i32*, i32** %_pA, i32 1 + %2 = load i32*, i32** %arrayidx1, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %2, i8* null, i32** nonnull %arrayidx1, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + store i32 99, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !2 + ret void +} +; CHECK-LABEL: Function: test_prp0_prp1: +; CHECK: NoAlias: store i32 99, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !2 <-> store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + +; Function Attrs: nofree nounwind +define dso_local void @test_prS0_prS1(%struct.FOO* nocapture %_pS) local_unnamed_addr #0 !noalias !11 { +entry: + %mpA = getelementptr inbounds %struct.FOO, %struct.FOO* %_pS, i32 0, i32 0 + %0 = load i32*, i32** %mpA, ptr_provenance i32** undef, align 4, !tbaa !14, !noalias !11 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %0, i8* null, i32** %mpA, i32** undef, i32 0, metadata !11), !tbaa !14, !noalias !11 + %mpB = getelementptr inbounds %struct.FOO, %struct.FOO* %_pS, i32 0, i32 1 + %2 = load i32*, i32** %mpB, ptr_provenance i32** undef, align 4, !tbaa !16, !noalias !11 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %2, i8* null, i32** nonnull %mpB, i32** undef, i32 0, metadata !11), !tbaa !16, !noalias !11 + store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !11 + store i32 99, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !11 + ret void +} +; CHECK-LABEL: Function: test_prS0_prS1: +; CHECK: NoAlias: store i32 99, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !11, !noalias !2 <-> store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !11, !noalias !2 + + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #1 + +attributes #0 = { nofree nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test_prp0_prp1: unknown scope"} +!4 = distinct !{!4, !"test_prp0_prp1"} +!5 = !{!6, !6, i64 0, i64 4} +!6 = !{!7, i64 4, !"any pointer"} +!7 = !{!8, i64 1, !"omnipotent char"} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!7, i64 4, !"int"} +!11 = !{!12} +!12 = distinct !{!12, !13, !"test_prS0_prS1: unknown scope"} +!13 = distinct !{!13, !"test_prS0_prS1"} +!14 = !{!15, !6, i64 0, i64 4} +!15 = !{!7, i64 8, !"FOO", !6, i64 0, i64 4, !6, i64 4, i64 4} +!16 = !{!15, !6, i64 4, i64 4} Index: llvm/test/Analysis/ScopedNoAliasAA/noalias_phi.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias_phi.ll @@ -0,0 +1,230 @@ +; RUN: opt < %s -basic-aa -scoped-noalias-aa -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nofree norecurse nounwind writeonly +define dso_local void @test_phi_p_p_p(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #0 { +entry: + %tobool = icmp eq i32 %c, 0 + br i1 %tobool, label %cond.false, label %cond.true + +cond.true: ; preds = %entry + br label %cond.end + +cond.false: ; preds = %entry + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32* [ %_pA, %cond.true ], [ %_pB, %cond.false ] + store i32 42, i32* %cond, ptr_provenance i32* undef, align 4, !tbaa !2 + store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2 + ret void +} +; CHECK-LABEL: Function: test_phi_p_p_p: +; CHECK: MayAlias: store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2 <-> store i32 42, i32* %cond, ptr_provenance i32* undef, align 4, !tbaa !2 + +; Function Attrs: nounwind +define dso_local void @test_phi_rp_p_p(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !6) + %tobool = icmp ne i32 %c, 0 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !6) + br i1 %tobool, label %cond.false, label %cond.true + +cond.true: ; preds = %entry + br label %cond.end + +cond.false: ; preds = %entry + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32* [ %_pA, %cond.true ], [ %_pB, %cond.false ] + %prov.cond = phi i32* [ %1, %cond.true ], [ %_pB, %cond.false ] + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !6 + store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2, !noalias !6 + ret void +} +; CHECK-LABEL: Function: test_phi_rp_p_p: +; CHECK: MayAlias: store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !5, !noalias !2 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !5, !noalias !2 + + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #2 + +; Function Attrs: nounwind +define dso_local void @test_phi_p_rp_p(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !9) + %tobool = icmp ne i32 %c, 0 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* %0, i32** null, i32** undef, i32 0, metadata !9) + br i1 %tobool, label %cond.false, label %cond.true + +cond.true: ; preds = %entry + br label %cond.end + +cond.false: ; preds = %entry + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32* [ %_pA, %cond.true ], [ %_pB, %cond.false ] + %prov.cond = phi i32* [ %_pA, %cond.true ], [ %1, %cond.false ] + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !9 + store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2, !noalias !9 + ret void +} +; CHECK-LABEL: Function: test_phi_p_rp_p: +; CHECK: MayAlias: store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !5, !noalias !2 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !5, !noalias !2 + +; Function Attrs: nounwind +define dso_local void @test_phi_rp_rp_p(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !12) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !15) + %tobool = icmp ne i32 %c, 0 + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !12) + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* %1, i32** null, i32** undef, i32 0, metadata !15) + br i1 %tobool, label %cond.false, label %cond.true + +cond.true: ; preds = %entry + br label %cond.end + +cond.false: ; preds = %entry + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32* [ %_pA, %cond.true ], [ %_pB, %cond.false ] + %prov.cond = phi i32* [ %2, %cond.true ], [ %3, %cond.false ] + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !17 + store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2, !noalias !17 + ret void +} +; CHECK-LABEL: Function: test_phi_rp_rp_p: +; CHECK: NoAlias: store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !7, !noalias !11 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !7, !noalias !11 + +; Function Attrs: nounwind +define dso_local void @test_phi_p_p_rp(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !18) + %tobool = icmp eq i32 %c, 0 + br i1 %tobool, label %cond.false, label %cond.true + +cond.true: ; preds = %entry + br label %cond.end + +cond.false: ; preds = %entry + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32* [ %_pA, %cond.true ], [ %_pB, %cond.false ] + store i32 42, i32* %cond, ptr_provenance i32* undef, align 4, !tbaa !2, !noalias !18 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pC, i8* %0, i32** null, i32** undef, i32 0, metadata !18), !tbaa !21, !noalias !18 + store i32 99, i32* %_pC, ptr_provenance i32* %1, align 4, !tbaa !2, !noalias !18 + ret void +} +; CHECK-LABEL: Function: test_phi_p_p_rp: +; CHECK: NoAlias: store i32 99, i32* %_pC, ptr_provenance i32* %1, align 4, !tbaa !5, !noalias !2 <-> store i32 42, i32* %cond, ptr_provenance i32* undef, align 4, !tbaa !5, !noalias !2 + +; Function Attrs: nounwind +define dso_local void @test_phi_rp_rp_rp_01(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !23) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !26) + %2 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !28) + %tobool = icmp ne i32 %c, 0 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !23) + %4 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* %1, i32** null, i32** undef, i32 0, metadata !26) + br i1 %tobool, label %cond.false, label %cond.true + +cond.true: ; preds = %entry + br label %cond.end + +cond.false: ; preds = %entry + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32* [ %_pA, %cond.true ], [ %_pB, %cond.false ] + %prov.cond = phi i32* [ %3, %cond.true ], [ %4, %cond.false ] + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !30 + %5 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pC, i8* %2, i32** null, i32** undef, i32 0, metadata !28), !tbaa !21, !noalias !30 + store i32 99, i32* %_pC, ptr_provenance i32* %5, align 4, !tbaa !2, !noalias !30 + ret void +} + +; CHECK-LABEL: Function: test_phi_rp_rp_rp_01: +; CHECK: NoAlias: store i32 99, i32* %_pC, ptr_provenance i32* %5, align 4, !tbaa !9, !noalias !13 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !9, !noalias !13 + +; Function Attrs: nounwind +define dso_local void @test_phi_rp_rp_rp_02(i32* nocapture %_pA, i32* nocapture readnone %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !31) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !34) + %tobool = icmp ne i32 %c, 0 + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !31) + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pC, i8* %1, i32** null, i32** undef, i32 0, metadata !34) + br i1 %tobool, label %cond.false, label %cond.true + +cond.true: ; preds = %entry + br label %cond.end + +cond.false: ; preds = %entry + br label %cond.end + +cond.end: ; preds = %cond.false, %cond.true + %cond = phi i32* [ %_pA, %cond.true ], [ %_pC, %cond.false ] + %prov.cond = phi i32* [ %2, %cond.true ], [ %3, %cond.false ] + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !36 + store i32 99, i32* %_pC, ptr_provenance i32* %3, align 4, !tbaa !2, !noalias !36 + ret void +} +; CHECK-LABEL: Function: test_phi_rp_rp_rp_02: +; CHECK: MayAlias: store i32 99, i32* %_pC, ptr_provenance i32* %3, align 4, !tbaa !7, !noalias !11 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !7, !noalias !11 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #3 + +attributes #0 = { nofree norecurse nounwind writeonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { argmemonly nounwind } +attributes #3 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3, !3, i64 0, i64 4} +!3 = !{!4, i64 4, !"int"} +!4 = !{!5, i64 1, !"omnipotent char"} +!5 = !{!"Simple C/C++ TBAA"} +!6 = !{!7} +!7 = distinct !{!7, !8, !"test_phi_rp_p_p: pA"} +!8 = distinct !{!8, !"test_phi_rp_p_p"} +!9 = !{!10} +!10 = distinct !{!10, !11, !"test_phi_p_rp_p: pB"} +!11 = distinct !{!11, !"test_phi_p_rp_p"} +!12 = !{!13} +!13 = distinct !{!13, !14, !"test_phi_rp_rp_p: pA"} +!14 = distinct !{!14, !"test_phi_rp_rp_p"} +!15 = !{!16} +!16 = distinct !{!16, !14, !"test_phi_rp_rp_p: pB"} +!17 = !{!13, !16} +!18 = !{!19} +!19 = distinct !{!19, !20, !"test_phi_p_p_rp: pC"} +!20 = distinct !{!20, !"test_phi_p_p_rp"} +!21 = !{!22, !22, i64 0, i64 4} +!22 = !{!4, i64 4, !"any pointer"} +!23 = !{!24} +!24 = distinct !{!24, !25, !"test_phi_rp_rp_rp_01: pA"} +!25 = distinct !{!25, !"test_phi_rp_rp_rp_01"} +!26 = !{!27} +!27 = distinct !{!27, !25, !"test_phi_rp_rp_rp_01: pB"} +!28 = !{!29} +!29 = distinct !{!29, !25, !"test_phi_rp_rp_rp_01: pC"} +!30 = !{!24, !27, !29} +!31 = !{!32} +!32 = distinct !{!32, !33, !"test_phi_rp_rp_rp_02: pA"} +!33 = distinct !{!33, !"test_phi_rp_rp_rp_02"} +!34 = !{!35} +!35 = distinct !{!35, !33, !"test_phi_rp_rp_rp_02: pC"} +!36 = !{!32, !37, !35} +!37 = distinct !{!37, !33, !"test_phi_rp_rp_rp_02: pB"} Index: llvm/test/Analysis/ScopedNoAliasAA/noalias_phi_in_loop.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias_phi_in_loop.ll @@ -0,0 +1,154 @@ +; RUN: opt < %s -basic-aa -scoped-noalias-aa -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind +define dso_local void @test_complex_phi_01(i32* nocapture %_pA, i32** nocapture readonly %_pB, i32 %n) local_unnamed_addr #0 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + %2 = load i32*, i32** %_pB, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx1 = getelementptr inbounds i32*, i32** %_pB, i32 1 + %3 = load i32*, i32** %arrayidx1, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx2 = getelementptr inbounds i32*, i32** %_pB, i32 2 + %4 = load i32*, i32** %arrayidx2, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx3 = getelementptr inbounds i32*, i32** %_pB, i32 3 + %5 = load i32*, i32** %arrayidx3, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx4 = getelementptr inbounds i32*, i32** %_pB, i32 4 + %6 = load i32*, i32** %arrayidx4, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx5 = getelementptr inbounds i32*, i32** %_pB, i32 5 + %7 = load i32*, i32** %arrayidx5, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx6 = getelementptr inbounds i32*, i32** %_pB, i32 6 + %8 = load i32*, i32** %arrayidx6, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx7 = getelementptr inbounds i32*, i32** %_pB, i32 7 + %9 = load i32*, i32** %arrayidx7, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx8 = getelementptr inbounds i32*, i32** %_pB, i32 8 + %10 = load i32*, i32** %arrayidx8, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx9 = getelementptr inbounds i32*, i32** %_pB, i32 9 + %11 = load i32*, i32** %arrayidx9, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + br label %for.cond + +for.cond: ; preds = %for.cond, %entry + %prov.pTmp00.0 = phi i32* [ %2, %entry ], [ %prov.pTmp01.0, %for.cond ] + %pTmp00.0 = phi i32* [ %2, %entry ], [ %pTmp01.0, %for.cond ] + %prov.pTmp01.0 = phi i32* [ %3, %entry ], [ %prov.pTmp02.0, %for.cond ] + %pTmp01.0 = phi i32* [ %3, %entry ], [ %pTmp02.0, %for.cond ] + %prov.pTmp02.0 = phi i32* [ %4, %entry ], [ %prov.pTmp03.0, %for.cond ] + %pTmp02.0 = phi i32* [ %4, %entry ], [ %pTmp03.0, %for.cond ] + %prov.pTmp03.0 = phi i32* [ %5, %entry ], [ %prov.pTmp04.0, %for.cond ] + %pTmp03.0 = phi i32* [ %5, %entry ], [ %pTmp04.0, %for.cond ] + %prov.pTmp04.0 = phi i32* [ %6, %entry ], [ %prov.pTmp05.0, %for.cond ] + %pTmp04.0 = phi i32* [ %6, %entry ], [ %pTmp05.0, %for.cond ] + %prov.pTmp05.0 = phi i32* [ %7, %entry ], [ %prov.pTmp06.0, %for.cond ] + %pTmp05.0 = phi i32* [ %7, %entry ], [ %pTmp06.0, %for.cond ] + %prov.pTmp06.0 = phi i32* [ %8, %entry ], [ %prov.pTmp07.0, %for.cond ] + %pTmp06.0 = phi i32* [ %8, %entry ], [ %pTmp07.0, %for.cond ] + %prov.pTmp07.0 = phi i32* [ %9, %entry ], [ %prov.pTmp08.0, %for.cond ] + %pTmp07.0 = phi i32* [ %9, %entry ], [ %pTmp08.0, %for.cond ] + %prov.pTmp08.0 = phi i32* [ %10, %entry ], [ %prov.pTmp09.0, %for.cond ] + %pTmp08.0 = phi i32* [ %10, %entry ], [ %pTmp09.0, %for.cond ] + %prov.pTmp09.0 = phi i32* [ %11, %entry ], [ %1, %for.cond ] + %pTmp09.0 = phi i32* [ %11, %entry ], [ %_pA, %for.cond ] + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.cond ] + %cmp = icmp slt i32 %i.0, %n + %inc = add nuw nsw i32 %i.0, 1 + br i1 %cmp, label %for.cond, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.cond + store i32 99, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + store i32 42, i32* %pTmp00.0, ptr_provenance i32* %prov.pTmp00.0, align 4, !tbaa !9, !noalias !2 + ret void +} + +; CHECK-LABEL: Function: test_complex_phi_01: +; CHECK: MayAlias: store i32 42, i32* %pTmp00.0, ptr_provenance i32* %prov.pTmp00.0, align 4, !tbaa !9, !noalias !2 <-> store i32 99, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + + +; Adapted version where the ptr_provenance chains don't collapse +; Function Attrs: nounwind +define dso_local void @test_complex_phi_02(i32* nocapture %_pA, i32** nocapture readonly %_pB, i32 %n) local_unnamed_addr #0 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %decl2 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 1, metadata !2) + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + %extra_ptr = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %decl2, i32** null, i32** undef, i32 1, metadata !2), !tbaa !5, !noalias !2 + %2 = load i32*, i32** %_pB, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx1 = getelementptr inbounds i32*, i32** %_pB, i32 1 + %3 = load i32*, i32** %arrayidx1, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx2 = getelementptr inbounds i32*, i32** %_pB, i32 2 + %4 = load i32*, i32** %arrayidx2, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx3 = getelementptr inbounds i32*, i32** %_pB, i32 3 + %5 = load i32*, i32** %arrayidx3, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx4 = getelementptr inbounds i32*, i32** %_pB, i32 4 + %6 = load i32*, i32** %arrayidx4, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx5 = getelementptr inbounds i32*, i32** %_pB, i32 5 + %7 = load i32*, i32** %arrayidx5, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx6 = getelementptr inbounds i32*, i32** %_pB, i32 6 + %8 = load i32*, i32** %arrayidx6, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx7 = getelementptr inbounds i32*, i32** %_pB, i32 7 + %9 = load i32*, i32** %arrayidx7, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx8 = getelementptr inbounds i32*, i32** %_pB, i32 8 + %10 = load i32*, i32** %arrayidx8, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + %arrayidx9 = getelementptr inbounds i32*, i32** %_pB, i32 9 + %11 = load i32*, i32** %arrayidx9, ptr_provenance i32** undef, align 4, !tbaa !5, !noalias !2 + br label %for.cond + +for.cond: ; preds = %for.cond, %entry + %prov.pTmp00.0 = phi i32* [ %2, %entry ], [ %prov.pTmp01.0, %for.cond ] + %pTmp00.0 = phi i32* [ %2, %entry ], [ %pTmp01.0, %for.cond ] + %prov.pTmp01.0 = phi i32* [ %3, %entry ], [ %prov.pTmp02.0, %for.cond ] + %pTmp01.0 = phi i32* [ %3, %entry ], [ %pTmp02.0, %for.cond ] + %prov.pTmp02.0 = phi i32* [ %4, %entry ], [ %prov.pTmp03.0, %for.cond ] + %pTmp02.0 = phi i32* [ %4, %entry ], [ %pTmp03.0, %for.cond ] + %prov.pTmp03.0 = phi i32* [ %5, %entry ], [ %prov.pTmp04.0, %for.cond ] + %pTmp03.0 = phi i32* [ %5, %entry ], [ %pTmp04.0, %for.cond ] + %prov.pTmp04.0 = phi i32* [ %6, %entry ], [ %prov.pTmp05.0, %for.cond ] + %pTmp04.0 = phi i32* [ %6, %entry ], [ %pTmp05.0, %for.cond ] + %prov.pTmp05.0 = phi i32* [ %7, %entry ], [ %prov.pTmp06.0, %for.cond ] + %pTmp05.0 = phi i32* [ %7, %entry ], [ %pTmp06.0, %for.cond ] + %prov.pTmp06.0 = phi i32* [ %8, %entry ], [ %prov.pTmp07.0, %for.cond ] + %pTmp06.0 = phi i32* [ %8, %entry ], [ %pTmp07.0, %for.cond ] + %prov.pTmp07.0 = phi i32* [ %9, %entry ], [ %prov.pTmp08.0, %for.cond ] + %pTmp07.0 = phi i32* [ %9, %entry ], [ %pTmp08.0, %for.cond ] + %prov.pTmp08.0 = phi i32* [ %10, %entry ], [ %prov.pTmp09.0, %for.cond ] + %pTmp08.0 = phi i32* [ %10, %entry ], [ %pTmp09.0, %for.cond ] + %prov.pTmp09.0 = phi i32* [ %11, %entry ], [ %extra_ptr, %for.cond ] + %pTmp09.0 = phi i32* [ %11, %entry ], [ %_pA, %for.cond ] + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.cond ] + %cmp = icmp slt i32 %i.0, %n + %inc = add nuw nsw i32 %i.0, 1 + br i1 %cmp, label %for.cond, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.cond + store i32 99, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + store i32 42, i32* %pTmp00.0, ptr_provenance i32* %prov.pTmp00.0, align 4, !tbaa !9, !noalias !2 + ret void +} + +; CHECK-LABEL: Function: test_complex_phi_02: +; CHECK: NoAlias: store i32 42, i32* %pTmp00.0, ptr_provenance i32* %prov.pTmp00.0, align 4, !tbaa !9, !noalias !2 <-> store i32 99, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test_complex_phi: rpTmp"} +!4 = distinct !{!4, !"test_complex_phi"} +!5 = !{!6, !6, i64 0, i64 4} +!6 = !{!7, i64 4, !"any pointer"} +!7 = !{!8, i64 1, !"omnipotent char"} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!7, i64 4, !"int"} Index: llvm/test/Analysis/ScopedNoAliasAA/noalias_recursive.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias_recursive.ll @@ -0,0 +1,127 @@ +; RUN: opt < %s -basic-aa -scoped-noalias-aa -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa,scoped-noalias-aa -passes=aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind +define dso_local void @test_prp_prp(i32** nocapture readonly %_pA, i32** nocapture readonly %_pB) local_unnamed_addr #0 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i64(i32*** null, i64 0, metadata !2) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i64(i32*** null, i64 0, metadata !5) + %2 = tail call i32** @llvm.provenance.noalias.p0p0i32.p0i8.p0p0p0i32.p0p0p0i32.i64(i32** %_pA, i8* %0, i32*** null, i32*** undef, i64 0, metadata !2), !tbaa !7, !noalias !11 + %3 = load i32*, i32** %_pA, ptr_provenance i32** %2, align 4, !tbaa !7, !noalias !11 + store i32 42, i32* %3, ptr_provenance i32* undef, align 4, !tbaa !12, !noalias !11 + %4 = tail call i32** @llvm.provenance.noalias.p0p0i32.p0i8.p0p0p0i32.p0p0p0i32.i64(i32** %_pB, i8* %1, i32*** null, i32*** undef, i64 0, metadata !5), !tbaa !7, !noalias !11 + %5 = load i32*, i32** %_pB, ptr_provenance i32** %4, align 4, !tbaa !7, !noalias !11 + store i32 99, i32* %5, ptr_provenance i32* undef, align 4, !tbaa !12, !noalias !11 + ret void +} +; CHECK-LABEL: Function: test_prp_prp: +; CHECK: MayAlias: store i32 99, i32* %5, ptr_provenance i32* undef, align 4, !tbaa !12, !noalias !11 <-> store i32 42, i32* %3, ptr_provenance i32* undef, align 4, !tbaa !12, !noalias !11 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i64(i32***, i64, metadata) #1 + +; Function Attrs: nofree nounwind +define dso_local void @test_rpp_rpp(i32** nocapture %_pA, i32** nocapture %_pB) local_unnamed_addr #2 !noalias !14 { +entry: + %0 = load i32*, i32** %_pA, ptr_provenance i32** undef, align 4, !tbaa !7, !noalias !14 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %0, i8* null, i32** %_pA, i32** undef, i64 0, metadata !14), !tbaa !7, !noalias !14 + store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !12, !noalias !14 + %2 = load i32*, i32** %_pB, ptr_provenance i32** undef, align 4, !tbaa !7, !noalias !14 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %2, i8* null, i32** %_pB, i32** undef, i64 0, metadata !14), !tbaa !7, !noalias !14 + store i32 99, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !12, !noalias !14 + ret void +} +; CHECK-LABEL: Function: test_rpp_rpp: +; CHECK: MayAlias: store i32 99, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !2 <-> store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + +; Function Attrs: nounwind +define dso_local void @test_rprp_rprp(i32** nocapture %_pA, i32** nocapture %_pB) local_unnamed_addr #0 !noalias !17 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i64(i32*** null, i64 0, metadata !20) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i64(i32*** null, i64 0, metadata !22) + %2 = tail call i32** @llvm.provenance.noalias.p0p0i32.p0i8.p0p0p0i32.p0p0p0i32.i64(i32** %_pA, i8* %0, i32*** null, i32*** undef, i64 0, metadata !20), !tbaa !7, !noalias !24 + %3 = load i32*, i32** %_pA, ptr_provenance i32** %2, align 4, !tbaa !7, !noalias !24 + %4 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %3, i8* null, i32** %_pA, i32** %2, i64 0, metadata !17), !tbaa !7, !noalias !24 + store i32 42, i32* %3, ptr_provenance i32* %4, align 4, !tbaa !12, !noalias !24 + %5 = tail call i32** @llvm.provenance.noalias.p0p0i32.p0i8.p0p0p0i32.p0p0p0i32.i64(i32** %_pB, i8* %1, i32*** null, i32*** undef, i64 0, metadata !22), !tbaa !7, !noalias !24 + %6 = load i32*, i32** %_pB, ptr_provenance i32** %5, align 4, !tbaa !7, !noalias !24 + %7 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %6, i8* null, i32** %_pB, i32** %5, i64 0, metadata !17), !tbaa !7, !noalias !24 + store i32 99, i32* %6, ptr_provenance i32* %7, align 4, !tbaa !12, !noalias !24 + ret void +} + +; CHECK-LABEL: Function: test_rprp_rprp: +; CHECK: NoAlias: store i32 99, i32* %6, ptr_provenance i32* %7, align 4, !tbaa !14, !noalias !13 <-> store i32 42, i32* %3, ptr_provenance i32* %4, align 4, !tbaa !14, !noalias !13 + +; Function Attrs: nounwind +define dso_local void @test_prp_01(i32** nocapture %pA) local_unnamed_addr #0 !noalias !17 { +entry: + %0 = load i32*, i32** %pA, ptr_provenance i32** undef, align 8, !tbaa !7, !noalias !17 + %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %0, i8* null, i32** %pA, i32** undef, i64 0, metadata !17), !tbaa !7, !noalias !17 + store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !12, !noalias !17 + %arrayidx1 = getelementptr inbounds i32*, i32** %pA, i64 0 + %2 = load i32*, i32** %arrayidx1, ptr_provenance i32** undef, align 8, !tbaa !7, !noalias !17 + %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %2, i8* null, i32** %arrayidx1, i32** undef, i64 0, metadata !17), !tbaa !7, !noalias !17 + store i32 43, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !12, !noalias !17 + ret void +} + +; CHECK-LABEL: Function: test_prp_01: +; CHECK: MayAlias: store i32 43, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !2 <-> store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 +; Function Attrs: nounwind +define dso_local void @test_prp_02(i32** nocapture %pA) local_unnamed_addr #0 !noalias !17 { +entry: + %0 = load i32*, i32** %pA, ptr_provenance i32** undef, align 8, !tbaa !7, !noalias !17 + %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %0, i8* null, i32** %pA, i32** undef, i64 0, metadata !17), !tbaa !7, !noalias !17 + store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !12, !noalias !17 + %arrayidx1 = getelementptr inbounds i32*, i32** %pA, i64 1 + %2 = load i32*, i32** %arrayidx1, ptr_provenance i32** undef, align 8, !tbaa !7, !noalias !17 + %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %2, i8* null, i32** %arrayidx1, i32** undef, i64 0, metadata !17), !tbaa !7, !noalias !17 + store i32 43, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !12, !noalias !17 + ret void +} + +; CHECK-LABEL: Function: test_prp_02: +; CHECK: NoAlias: store i32 43, i32* %2, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !2 <-> store i32 42, i32* %0, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + +; Function Attrs: nounwind readnone speculatable +declare i32** @llvm.provenance.noalias.p0p0i32.p0i8.p0p0p0i32.p0p0p0i32.i64(i32**, i8*, i32***, i32***, i64, metadata) #3 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32*, i8*, i32**, i32**, i64, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nofree nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test_prp_prp: pA"} +!4 = distinct !{!4, !"test_prp_prp"} +!5 = !{!6} +!6 = distinct !{!6, !4, !"test_prp_prp: pB"} +!7 = !{!8, !8, i64 0, i64 4} +!8 = !{!9, i64 4, !"any pointer"} +!9 = !{!10, i64 1, !"omnipotent char"} +!10 = !{!"Simple C/C++ TBAA"} +!11 = !{!3, !6} +!12 = !{!13, !13, i64 0, i64 4} +!13 = !{!9, i64 4, !"int"} +!14 = !{!15} +!15 = distinct !{!15, !16, !"test_rpp_rpp: unknown scope"} +!16 = distinct !{!16, !"test_rpp_rpp"} +!17 = !{!18} +!18 = distinct !{!18, !19, !"test_rprp_rprp: unknown scope"} +!19 = distinct !{!19, !"test_rprp_rprp"} +!20 = !{!21} +!21 = distinct !{!21, !19, !"test_rprp_rprp: pA"} +!22 = !{!23} +!23 = distinct !{!23, !19, !"test_rprp_rprp: pB"} +!24 = !{!21, !23, !18} Index: llvm/test/Analysis/ScopedNoAliasAA/noalias_select.ll =================================================================== --- /dev/null +++ llvm/test/Analysis/ScopedNoAliasAA/noalias_select.ll @@ -0,0 +1,167 @@ +; RUN: opt < %s -basic-aa -scoped-noalias-aa -aa-eval -evaluate-aa-metadata -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nofree norecurse nounwind writeonly +define dso_local void @test_select_p_p_p(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #0 { +entry: + %tobool = icmp eq i32 %c, 0 + %cond = select i1 %tobool, i32* %_pB, i32* %_pA + store i32 42, i32* %cond, ptr_provenance i32* undef, align 4, !tbaa !2 + store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2 + ret void +} +; CHECK-LABEL: Function: test_select_p_p_p: +; CHECK: MayAlias: store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2 <-> store i32 42, i32* %cond, ptr_provenance i32* undef, align 4, !tbaa !2 + +; Function Attrs: nounwind +define dso_local void @test_select_rp_p_p(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !6) + %tobool = icmp ne i32 %c, 0 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !6) + %prov.cond = select i1 %tobool, i32* %1, i32* %_pB + %cond = select i1 %tobool, i32* %_pA, i32* %_pB + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !6 + store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2, !noalias !6 + ret void +} +; CHECK-LABEL: Function: test_select_rp_p_p: +; CHECK: MayAlias: store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !5, !noalias !2 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !5, !noalias !2 + + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #2 + +; Function Attrs: nounwind +define dso_local void @test_select_p_rp_p(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !9) + %tobool = icmp ne i32 %c, 0 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* %0, i32** null, i32** undef, i32 0, metadata !9) + %prov.cond = select i1 %tobool, i32* %_pA, i32* %1 + %cond = select i1 %tobool, i32* %_pA, i32* %_pB + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !9 + store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2, !noalias !9 + ret void +} +; CHECK-LABEL: Function: test_select_p_rp_p: +; CHECK: MayAlias: store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !5, !noalias !2 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !5, !noalias !2 + +; Function Attrs: nounwind +define dso_local void @test_select_rp_rp_p(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !12) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !15) + %tobool = icmp ne i32 %c, 0 + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !12) + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* %1, i32** null, i32** undef, i32 0, metadata !15) + %prov.cond = select i1 %tobool, i32* %2, i32* %3 + %cond = select i1 %tobool, i32* %_pA, i32* %_pB + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !17 + store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !2, !noalias !17 + ret void +} +; CHECK-LABEL: Function: test_select_rp_rp_p: +; CHECK: NoAlias: store i32 99, i32* %_pC, ptr_provenance i32* undef, align 4, !tbaa !7, !noalias !11 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !7, !noalias !11 + +; Function Attrs: nounwind +define dso_local void @test_select_p_p_rp(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !18) + %tobool = icmp eq i32 %c, 0 + %cond = select i1 %tobool, i32* %_pB, i32* %_pA + store i32 42, i32* %cond, ptr_provenance i32* undef, align 4, !tbaa !2, !noalias !18 + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pC, i8* %0, i32** null, i32** undef, i32 0, metadata !18), !tbaa !21, !noalias !18 + store i32 99, i32* %_pC, ptr_provenance i32* %1, align 4, !tbaa !2, !noalias !18 + ret void +} +; CHECK-LABEL: Function: test_select_p_p_rp: +; CHECK: NoAlias: store i32 99, i32* %_pC, ptr_provenance i32* %1, align 4, !tbaa !5, !noalias !2 <-> store i32 42, i32* %cond, ptr_provenance i32* undef, align 4, !tbaa !5, !noalias !2 + +; Function Attrs: nounwind +define dso_local void @test_select_rp_rp_rp_01(i32* nocapture %_pA, i32* nocapture %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !23) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !26) + %2 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !28) + %tobool = icmp ne i32 %c, 0 + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !23) + %4 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pB, i8* %1, i32** null, i32** undef, i32 0, metadata !26) + %prov.cond = select i1 %tobool, i32* %3, i32* %4 + %cond = select i1 %tobool, i32* %_pA, i32* %_pB + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !30 + %5 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pC, i8* %2, i32** null, i32** undef, i32 0, metadata !28), !tbaa !21, !noalias !30 + store i32 99, i32* %_pC, ptr_provenance i32* %5, align 4, !tbaa !2, !noalias !30 + ret void +} + +; CHECK-LABEL: Function: test_select_rp_rp_rp_01: +; CHECK: NoAlias: store i32 99, i32* %_pC, ptr_provenance i32* %5, align 4, !tbaa !9, !noalias !13 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !9, !noalias !13 + +; Function Attrs: nounwind +define dso_local void @test_select_rp_rp_rp_02(i32* nocapture %_pA, i32* nocapture readnone %_pB, i32* nocapture %_pC, i32 %c) local_unnamed_addr #1 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !31) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !34) + %tobool = icmp ne i32 %c, 0 + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !31) + %3 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pC, i8* %1, i32** null, i32** undef, i32 0, metadata !34) + %prov.cond = select i1 %tobool, i32* %2, i32* %3 + %cond = select i1 %tobool, i32* %_pA, i32* %_pC + store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !2, !noalias !36 + store i32 99, i32* %_pC, ptr_provenance i32* %3, align 4, !tbaa !2, !noalias !36 + ret void +} +; CHECK-LABEL: Function: test_select_rp_rp_rp_02: +; CHECK: MayAlias: store i32 99, i32* %_pC, ptr_provenance i32* %3, align 4, !tbaa !7, !noalias !11 <-> store i32 42, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !7, !noalias !11 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #3 + +attributes #0 = { nofree norecurse nounwind writeonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { argmemonly nounwind } +attributes #3 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3, !3, i64 0, i64 4} +!3 = !{!4, i64 4, !"int"} +!4 = !{!5, i64 1, !"omnipotent char"} +!5 = !{!"Simple C/C++ TBAA"} +!6 = !{!7} +!7 = distinct !{!7, !8, !"test_select_rp_p_p: pA"} +!8 = distinct !{!8, !"test_select_rp_p_p"} +!9 = !{!10} +!10 = distinct !{!10, !11, !"test_select_p_rp_p: pB"} +!11 = distinct !{!11, !"test_select_p_rp_p"} +!12 = !{!13} +!13 = distinct !{!13, !14, !"test_select_rp_rp_p: pA"} +!14 = distinct !{!14, !"test_select_rp_rp_p"} +!15 = !{!16} +!16 = distinct !{!16, !14, !"test_select_rp_rp_p: pB"} +!17 = !{!13, !16} +!18 = !{!19} +!19 = distinct !{!19, !20, !"test_select_p_p_rp: pC"} +!20 = distinct !{!20, !"test_select_p_p_rp"} +!21 = !{!22, !22, i64 0, i64 4} +!22 = !{!4, i64 4, !"any pointer"} +!23 = !{!24} +!24 = distinct !{!24, !25, !"test_select_rp_rp_rp_01: pA"} +!25 = distinct !{!25, !"test_select_rp_rp_rp_01"} +!26 = !{!27} +!27 = distinct !{!27, !25, !"test_select_rp_rp_rp_01: pB"} +!28 = !{!29} +!29 = distinct !{!29, !25, !"test_select_rp_rp_rp_01: pC"} +!30 = !{!24, !27, !29} +!31 = !{!32} +!32 = distinct !{!32, !33, !"test_select_rp_rp_rp_02: pA"} +!33 = distinct !{!33, !"test_select_rp_rp_rp_02"} +!34 = !{!35} +!35 = distinct !{!35, !33, !"test_select_rp_rp_rp_02: pC"} +!36 = !{!32, !37, !35} +!37 = distinct !{!37, !33, !"test_select_rp_rp_rp_02: pB"} Index: llvm/test/Bitcode/compatibility.ll =================================================================== --- llvm/test/Bitcode/compatibility.ll +++ llvm/test/Bitcode/compatibility.ll @@ -828,12 +828,26 @@ %ld.3 = load atomic volatile i32, i32* %word syncscope("singlethread") seq_cst, align 16 ; CHECK: %ld.3 = load atomic volatile i32, i32* %word syncscope("singlethread") seq_cst, align 16 + %ld.1p = load atomic i32, i32* %word monotonic, ptr_provenance i32* %word, align 4 + ; CHECK: %ld.1p = load atomic i32, i32* %word monotonic, ptr_provenance i32* %word, align 4 + %ld.2p = load atomic volatile i32, i32* %word acquire, ptr_provenance i32* %word, align 8 + ; CHECK: %ld.2p = load atomic volatile i32, i32* %word acquire, ptr_provenance i32* %word, align 8 + %ld.3p = load atomic volatile i32, i32* %word syncscope("singlethread") seq_cst, ptr_provenance i32* %word, align 16 + ; CHECK: %ld.3p = load atomic volatile i32, i32* %word syncscope("singlethread") seq_cst, ptr_provenance i32* %word, align 16 + store atomic i32 23, i32* %word monotonic, align 4 ; CHECK: store atomic i32 23, i32* %word monotonic, align 4 store atomic volatile i32 24, i32* %word monotonic, align 4 ; CHECK: store atomic volatile i32 24, i32* %word monotonic, align 4 store atomic volatile i32 25, i32* %word syncscope("singlethread") monotonic, align 4 ; CHECK: store atomic volatile i32 25, i32* %word syncscope("singlethread") monotonic, align 4 + + store atomic i32 26, i32* %word monotonic, ptr_provenance i32* %word, align 4 + ; CHECK: store atomic i32 26, i32* %word monotonic, ptr_provenance i32* %word, align 4 + store atomic volatile i32 27, i32* %word monotonic, ptr_provenance i32* %word, align 4 + ; CHECK: store atomic volatile i32 27, i32* %word monotonic, ptr_provenance i32* %word, align 4 + store atomic volatile i32 28, i32* %word syncscope("singlethread") monotonic, ptr_provenance i32* %word, align 4 + ; CHECK: store atomic volatile i32 28, i32* %word syncscope("singlethread") monotonic, ptr_provenance i32* %word, align 4 ret void } @@ -1388,11 +1402,21 @@ load volatile i32*, i32** %base, align 8, !invariant.load !7, !nontemporal !8, !nonnull !7, !dereferenceable !9, !dereferenceable_or_null !9 ; CHECK: load volatile i32*, i32** %base, align 8, !invariant.load !7, !nontemporal !8, !nonnull !7, !dereferenceable !9, !dereferenceable_or_null !9 + load i32*, i32** %base, ptr_provenance i32** %base, align 8, !invariant.load !7, !nontemporal !8, !nonnull !7, !dereferenceable !9, !dereferenceable_or_null !9 + ; CHECK: load i32*, i32** %base, ptr_provenance i32** %base, align 8, !invariant.load !7, !nontemporal !8, !nonnull !7, !dereferenceable !9, !dereferenceable_or_null !9 + load volatile i32*, i32** %base, ptr_provenance i32** %base, align 8, !invariant.load !7, !nontemporal !8, !nonnull !7, !dereferenceable !9, !dereferenceable_or_null !9 + ; CHECK: load volatile i32*, i32** %base, ptr_provenance i32** %base, align 8, !invariant.load !7, !nontemporal !8, !nonnull !7, !dereferenceable !9, !dereferenceable_or_null !9 + store i32* null, i32** %base, align 4, !nontemporal !8 ; CHECK: store i32* null, i32** %base, align 4, !nontemporal !8 store volatile i32* null, i32** %base, align 4, !nontemporal !8 ; CHECK: store volatile i32* null, i32** %base, align 4, !nontemporal !8 + store i32* null, i32** %base, ptr_provenance i32** %base, align 4, !nontemporal !8 + ; CHECK: store i32* null, i32** %base, ptr_provenance i32** %base, align 4, !nontemporal !8 + store volatile i32* null, i32** %base, ptr_provenance i32** %base, align 4, !nontemporal !8 + ; CHECK: store volatile i32* null, i32** %base, ptr_provenance i32** %base, align 4, !nontemporal !8 + ret void } Index: llvm/test/Bitcode/loadstore_ptr_provenance.ll =================================================================== --- /dev/null +++ llvm/test/Bitcode/loadstore_ptr_provenance.ll @@ -0,0 +1,44 @@ +; RUN: opt --verify -S < %s | FileCheck %s +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +; RUN: verify-uselistorder < %s + +define i32 @f(i32* %p, i32* %q, i32* %word, i32** %base) { + ; CHECK: define i32 @f(i32* %p, i32* %q, i32* %word, i32** %base) { + store i32 42, i32* %p, ptr_provenance i32* %p + ; CHECK-NEXT: store i32 42, i32* %p, ptr_provenance i32* %p + store i32 43, i32* %q, ptr_provenance i32* %q + ; CHECK-NEXT: store i32 43, i32* %q, ptr_provenance i32* %q + %r = load i32, i32* %p, ptr_provenance i32* %p + ; CHECK-NEXT: %r = load i32, i32* %p, ptr_provenance i32* %p + + %ld.1p = load atomic i32, i32* %word monotonic, ptr_provenance i32* %word, align 4 + ; CHECK: %ld.1p = load atomic i32, i32* %word monotonic, ptr_provenance i32* %word, align 4 + %ld.2p = load atomic volatile i32, i32* %word acquire, ptr_provenance i32* %word, align 8 + ; CHECK: %ld.2p = load atomic volatile i32, i32* %word acquire, ptr_provenance i32* %word, align 8 + %ld.3p = load atomic volatile i32, i32* %word syncscope("singlethread") seq_cst, ptr_provenance i32* %word, align 16 + ; CHECK: %ld.3p = load atomic volatile i32, i32* %word syncscope("singlethread") seq_cst, ptr_provenance i32* %word, align 16 + + store atomic i32 23, i32* %word monotonic, align 4 + ; CHECK: store atomic i32 23, i32* %word monotonic, align 4 + store atomic volatile i32 24, i32* %word monotonic, align 4 + ; CHECK: store atomic volatile i32 24, i32* %word monotonic, align 4 + store atomic volatile i32 25, i32* %word syncscope("singlethread") monotonic, align 4 + ; CHECK: store atomic volatile i32 25, i32* %word syncscope("singlethread") monotonic, align 4 + + load i32*, i32** %base, ptr_provenance i32** %base, align 8, !invariant.load !0, !nontemporal !1, !nonnull !0, !dereferenceable !2, !dereferenceable_or_null !2 + ; CHECK: load i32*, i32** %base, ptr_provenance i32** %base, align 8, !invariant.load !0, !nontemporal !1, !nonnull !0, !dereferenceable !2, !dereferenceable_or_null !2 + load volatile i32*, i32** %base, ptr_provenance i32** %base, align 8, !invariant.load !0, !nontemporal !1, !nonnull !0, !dereferenceable !2, !dereferenceable_or_null !2 + ; CHECK: load volatile i32*, i32** %base, ptr_provenance i32** %base, align 8, !invariant.load !0, !nontemporal !1, !nonnull !0, !dereferenceable !2, !dereferenceable_or_null !2 + + store i32* null, i32** %base, ptr_provenance i32** %base, align 4, !nontemporal !1 + ; CHECK: store i32* null, i32** %base, ptr_provenance i32** %base, align 4, !nontemporal !1 + store volatile i32* null, i32** %base, ptr_provenance i32** %base, align 4, !nontemporal !1 + ; CHECK: store volatile i32* null, i32** %base, ptr_provenance i32** %base, align 4, !nontemporal !1 + + ret i32 %r + ; CHECK-NEXT: ret i32 %r +} + +!0 = !{i32 1} +!1 = !{} +!2 = !{i64 4} Index: llvm/test/CodeGen/AMDGPU/opt-pipeline.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/opt-pipeline.ll +++ llvm/test/CodeGen/AMDGPU/opt-pipeline.ll @@ -44,8 +44,10 @@ ; GCN-O1-NEXT: Lower 'expect' Intrinsics ; GCN-O1-NEXT: Simplify the CFG ; GCN-O1-NEXT: Dominator Tree Construction +; GCN-O1-NEXT: Connect llvm.noalias.decl ; GCN-O1-NEXT: SROA ; GCN-O1-NEXT: Early CSE +; GCN-O1-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O1-NEXT: Pass Arguments: ; GCN-O1-NEXT: Target Library Information @@ -95,7 +97,10 @@ ; GCN-O1-NEXT: Globals Alias Analysis ; GCN-O1-NEXT: Call Graph SCC Pass Manager ; GCN-O1-NEXT: Remove unused exception handling info -; GCN-O1-NEXT: Function Integration/Inlining +; GCN-O1-NEXT: Integration/Inlining +; GCN-O1-NEXT: FunctionPass Manager +; GCN-O1-NEXT: Dominator Tree Construction +; GCN-O1-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O1-NEXT: Deduce function attributes ; GCN-O1-NEXT: FunctionPass Manager ; GCN-O1-NEXT: Infer address spaces @@ -103,11 +108,13 @@ ; GCN-O1-NEXT: FunctionPass Manager ; GCN-O1-NEXT: AMDGPU Promote Alloca to vector ; GCN-O1-NEXT: Dominator Tree Construction +; GCN-O1-NEXT: Connect llvm.noalias.decl ; GCN-O1-NEXT: SROA ; GCN-O1-NEXT: Basic Alias Analysis (stateless AA impl) ; GCN-O1-NEXT: Function Alias Analysis Results ; GCN-O1-NEXT: Memory SSA ; GCN-O1-NEXT: Early CSE w/ MemorySSA +; GCN-O1-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O1-NEXT: Simplify the CFG ; GCN-O1-NEXT: Dominator Tree Construction ; GCN-O1-NEXT: Basic Alias Analysis (stateless AA impl) @@ -165,15 +172,21 @@ ; GCN-O1-NEXT: Induction Variable Simplification ; GCN-O1-NEXT: Delete dead loops ; GCN-O1-NEXT: Unroll loops +; GCN-O1-NEXT: Connect llvm.noalias.decl ; GCN-O1-NEXT: SROA +; GCN-O1-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O1-NEXT: Sparse Conditional Constant Propagation ; GCN-O1-NEXT: Demanded bits analysis ; GCN-O1-NEXT: Bit-Tracking Dead Code Elimination +; GCN-O1-NEXT: Basic Alias Analysis (stateless AA impl) ; GCN-O1-NEXT: Function Alias Analysis Results +; GCN-O1-NEXT: Natural Loop Information ; GCN-O1-NEXT: Lazy Branch Probability Analysis ; GCN-O1-NEXT: Lazy Block Frequency Analysis ; GCN-O1-NEXT: Optimization Remark Emitter ; GCN-O1-NEXT: Combine redundant instructions +; GCN-O1-NEXT: Connect llvm.noalias.decl +; GCN-O1-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O1-NEXT: Post-Dominator Tree Construction ; GCN-O1-NEXT: Aggressive Dead Code Elimination ; GCN-O1-NEXT: Basic Alias Analysis (stateless AA impl) @@ -353,8 +366,10 @@ ; GCN-O2-NEXT: Lower 'expect' Intrinsics ; GCN-O2-NEXT: Simplify the CFG ; GCN-O2-NEXT: Dominator Tree Construction +; GCN-O2-NEXT: Connect llvm.noalias.decl ; GCN-O2-NEXT: SROA ; GCN-O2-NEXT: Early CSE +; GCN-O2-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O2-NEXT: Pass Arguments: ; GCN-O2-NEXT: Target Library Information @@ -404,7 +419,10 @@ ; GCN-O2-NEXT: Globals Alias Analysis ; GCN-O2-NEXT: Call Graph SCC Pass Manager ; GCN-O2-NEXT: Remove unused exception handling info -; GCN-O2-NEXT: Function Integration/Inlining +; GCN-O2-NEXT: Integration/Inlining +; GCN-O2-NEXT: FunctionPass Manager +; GCN-O2-NEXT: Dominator Tree Construction +; GCN-O2-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O2-NEXT: OpenMP specific optimizations ; GCN-O2-NEXT: Deduce function attributes ; GCN-O2-NEXT: FunctionPass Manager @@ -418,12 +436,15 @@ ; GCN-O2-NEXT: FunctionPass Manager ; GCN-O2-NEXT: AMDGPU Promote Alloca to vector ; GCN-O2-NEXT: Dominator Tree Construction +; GCN-O2-NEXT: Connect llvm.noalias.decl ; GCN-O2-NEXT: SROA ; GCN-O2-NEXT: Basic Alias Analysis (stateless AA impl) ; GCN-O2-NEXT: Function Alias Analysis Results ; GCN-O2-NEXT: Memory SSA ; GCN-O2-NEXT: Early CSE w/ MemorySSA +; GCN-O2-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O2-NEXT: Speculatively execute instructions if target has divergent branches +; GCN-O2-NEXT: Basic Alias Analysis (stateless AA impl) ; GCN-O2-NEXT: Function Alias Analysis Results ; GCN-O2-NEXT: Lazy Value Information Analysis ; GCN-O2-NEXT: Jump Threading @@ -492,9 +513,13 @@ ; GCN-O2-NEXT: Induction Variable Simplification ; GCN-O2-NEXT: Delete dead loops ; GCN-O2-NEXT: Unroll loops +; GCN-O2-NEXT: Connect llvm.noalias.decl ; GCN-O2-NEXT: SROA +; GCN-O2-NEXT: Propagate and Convert Noalias intrinsics +; GCN-O2-NEXT: Basic Alias Analysis (stateless AA impl) ; GCN-O2-NEXT: Function Alias Analysis Results ; GCN-O2-NEXT: MergedLoadStoreMotion +; GCN-O2-NEXT: Natural Loop Information ; GCN-O2-NEXT: Phi Values Analysis ; GCN-O2-NEXT: Function Alias Analysis Results ; GCN-O2-NEXT: Memory Dependence Analysis @@ -511,6 +536,10 @@ ; GCN-O2-NEXT: Lazy Block Frequency Analysis ; GCN-O2-NEXT: Optimization Remark Emitter ; GCN-O2-NEXT: Combine redundant instructions +; GCN-O2-NEXT: Connect llvm.noalias.decl +; GCN-O2-NEXT: Propagate and Convert Noalias intrinsics +; GCN-O2-NEXT: Basic Alias Analysis (stateless AA impl) +; GCN-O2-NEXT: Function Alias Analysis Results ; GCN-O2-NEXT: Lazy Value Information Analysis ; GCN-O2-NEXT: Jump Threading ; GCN-O2-NEXT: Value Propagation @@ -712,8 +741,10 @@ ; GCN-O3-NEXT: Lower 'expect' Intrinsics ; GCN-O3-NEXT: Simplify the CFG ; GCN-O3-NEXT: Dominator Tree Construction +; GCN-O3-NEXT: Connect llvm.noalias.decl ; GCN-O3-NEXT: SROA ; GCN-O3-NEXT: Early CSE +; GCN-O3-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O3-NEXT: Pass Arguments: ; GCN-O3-NEXT: Target Library Information @@ -766,7 +797,10 @@ ; GCN-O3-NEXT: Globals Alias Analysis ; GCN-O3-NEXT: Call Graph SCC Pass Manager ; GCN-O3-NEXT: Remove unused exception handling info -; GCN-O3-NEXT: Function Integration/Inlining +; GCN-O3-NEXT: Integration/Inlining +; GCN-O3-NEXT: FunctionPass Manager +; GCN-O3-NEXT: Dominator Tree Construction +; GCN-O3-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O3-NEXT: OpenMP specific optimizations ; GCN-O3-NEXT: Deduce function attributes ; GCN-O3-NEXT: Promote 'by reference' arguments to scalars @@ -781,12 +815,15 @@ ; GCN-O3-NEXT: FunctionPass Manager ; GCN-O3-NEXT: AMDGPU Promote Alloca to vector ; GCN-O3-NEXT: Dominator Tree Construction +; GCN-O3-NEXT: Connect llvm.noalias.decl ; GCN-O3-NEXT: SROA ; GCN-O3-NEXT: Basic Alias Analysis (stateless AA impl) ; GCN-O3-NEXT: Function Alias Analysis Results ; GCN-O3-NEXT: Memory SSA ; GCN-O3-NEXT: Early CSE w/ MemorySSA +; GCN-O3-NEXT: Propagate and Convert Noalias intrinsics ; GCN-O3-NEXT: Speculatively execute instructions if target has divergent branches +; GCN-O3-NEXT: Basic Alias Analysis (stateless AA impl) ; GCN-O3-NEXT: Function Alias Analysis Results ; GCN-O3-NEXT: Lazy Value Information Analysis ; GCN-O3-NEXT: Jump Threading @@ -856,9 +893,13 @@ ; GCN-O3-NEXT: Induction Variable Simplification ; GCN-O3-NEXT: Delete dead loops ; GCN-O3-NEXT: Unroll loops +; GCN-O3-NEXT: Connect llvm.noalias.decl ; GCN-O3-NEXT: SROA +; GCN-O3-NEXT: Propagate and Convert Noalias intrinsics +; GCN-O3-NEXT: Basic Alias Analysis (stateless AA impl) ; GCN-O3-NEXT: Function Alias Analysis Results ; GCN-O3-NEXT: MergedLoadStoreMotion +; GCN-O3-NEXT: Natural Loop Information ; GCN-O3-NEXT: Phi Values Analysis ; GCN-O3-NEXT: Function Alias Analysis Results ; GCN-O3-NEXT: Memory Dependence Analysis @@ -875,6 +916,10 @@ ; GCN-O3-NEXT: Lazy Block Frequency Analysis ; GCN-O3-NEXT: Optimization Remark Emitter ; GCN-O3-NEXT: Combine redundant instructions +; GCN-O3-NEXT: Connect llvm.noalias.decl +; GCN-O3-NEXT: Propagate and Convert Noalias intrinsics +; GCN-O3-NEXT: Basic Alias Analysis (stateless AA impl) +; GCN-O3-NEXT: Function Alias Analysis Results ; GCN-O3-NEXT: Lazy Value Information Analysis ; GCN-O3-NEXT: Jump Threading ; GCN-O3-NEXT: Value Propagation Index: llvm/test/CodeGen/Generic/noalias.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/Generic/noalias.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s + +define i32* @test(i32* %p) { + %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !0) + %v = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %p, i8* %p.decl, i32** null, i32 0, metadata !0) + ret i32* %v +} + +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) argmemonly nounwind +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) argmemonly nounwind speculatable + +!0 = !{!0, !"some domain"} +!1 = !{!1, !0, !"some scope"} Index: llvm/test/CodeGen/Generic/provenance.noalias.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/Generic/provenance.noalias.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s + +define i32* @test(i32* %p) { + %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !0) + %p.provenance = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %p, i8* %p.decl, i32** null, i32** undef, i32 0, metadata !0) + %p.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %p, i32* %p.provenance) + ret i32* %p.guard +} + +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) argmemonly nounwind +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) argmemonly nounwind speculatable +declare i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32*, i32*) nounwind readnone + +!0 = !{!0, !"some domain"} +!1 = !{!1, !0, !"some scope"} Index: llvm/test/Other/new-pm-defaults.ll =================================================================== --- llvm/test/Other/new-pm-defaults.ll +++ llvm/test/Other/new-pm-defaults.ll @@ -85,10 +85,12 @@ ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O-NEXT: Running pass: CoroEarlyPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: OpenMPOptPass @@ -129,9 +131,11 @@ ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass on (foo) ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass on (foo) ; CHECK-EP-CGSCC-LATE-NEXT: Running pass: NoOpCGSCCPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -169,7 +173,9 @@ ; CHECK-O-NEXT: Running pass: LoopDeletionPass ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass ; CHECK-EP-LOOP-END-NEXT: Running pass: NoOpLoopPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass on foo +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-MATRIX: Running pass: VectorCombinePass ; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass ; CHECK-O23SZ-NEXT: Running pass: GVNPass @@ -181,6 +187,8 @@ ; CHECK-O-NEXT: Running analysis: DemandedBitsAnalysis ; CHECK-O-NEXT: Running pass: InstCombinePass ; CHECK-EP-PEEPHOLE-NEXT: Running pass: NoOpFunctionPass +; CHECK-O23SZ-NEXT: Running pass: ConnectNoAliasDeclPass on foo +; CHECK-O23SZ-NEXT: Running pass: PropagateAndConvertNoAliasPass on foo ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis ; CHECK-O23SZ-NEXT: Running pass: CorrelatedValuePropagationPass Index: llvm/test/Other/new-pm-lto-defaults.ll =================================================================== --- llvm/test/Other/new-pm-lto-defaults.ll +++ llvm/test/Other/new-pm-lto-defaults.ll @@ -80,7 +80,9 @@ ; CHECK-EP-Peephole-NEXT: Running pass: NoOpFunctionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis +; CHECK-O23SZ-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O23SZ-NEXT: Running pass: SROAPass on foo +; CHECK-O23SZ-NEXT: Running pass: PropagateAndConvertNoAliasPass on foo ; CHECK-O23SZ-NEXT: Running pass: TailCallElimPass on foo ; CHECK-O23SZ-NEXT: Running pass: PostOrderFunctionAttrsPass on (foo) ; CHECK-O23SZ-NEXT: Running pass: RequireAnalysisPass<{{.*}}GlobalsAA Index: llvm/test/Other/new-pm-pgo-preinline.ll =================================================================== --- llvm/test/Other/new-pm-pgo-preinline.ll +++ llvm/test/Other/new-pm-pgo-preinline.ll @@ -9,8 +9,10 @@ ; CHECK-Osz-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-Osz-NEXT: Running pass: InlinerPass on (foo) ; CHECK-Osz-NEXT: Running pass: InlinerPass on (foo) +; CHECK-Osz-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-Osz-NEXT: Running pass: SROAPass on foo ; CHECK-Osz-NEXT: Running pass: EarlyCSEPass on foo +; CHECK-Osz-NEXT: Running pass: PropagateAndConvertNoAliasPass on foo ; CHECK-Osz-NEXT: Running pass: SimplifyCFGPass on foo ; CHECK-Osz-NEXT: Running pass: InstCombinePass on foo ; CHECK-Osz-NEXT: Invalidating analysis: InlineAdvisorAnalysis Index: llvm/test/Other/new-pm-thinlto-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-defaults.ll +++ llvm/test/Other/new-pm-thinlto-defaults.ll @@ -66,10 +66,12 @@ ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O-NEXT: Running pass: CoroEarlyPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: OpenMPOptPass @@ -108,9 +110,11 @@ ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass on (foo) ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass on (foo) +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -145,7 +149,9 @@ ; CHECK-O-NEXT: Running pass: IndVarSimplifyPass ; CHECK-O-NEXT: Running pass: LoopDeletionPass ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass on foo +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-Os-NEXT: Running pass: MergedLoadStoreMotionPass ; CHECK-Os-NEXT: Running pass: GVNPass ; CHECK-Os-NEXT: Running analysis: MemoryDependenceAnalysis @@ -167,6 +173,8 @@ ; CHECK-O-NEXT: Running pass: BDCEPass ; CHECK-O-NEXT: Running analysis: DemandedBitsAnalysis ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O23SZ-NEXT: Running pass: ConnectNoAliasDeclPass on foo +; CHECK-O23SZ-NEXT: Running pass: PropagateAndConvertNoAliasPass on foo ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis ; CHECK-O23SZ-NEXT: Running pass: CorrelatedValuePropagationPass Index: llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll +++ llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll @@ -36,10 +36,12 @@ ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O-NEXT: Running pass: CoroEarlyPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: OpenMPOptPass @@ -82,9 +84,11 @@ ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -118,7 +122,9 @@ ; CHECK-O-NEXT: Running pass: IndVarSimplifyPass ; CHECK-O-NEXT: Running pass: LoopDeletionPass ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass on foo +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-Os-NEXT: Running pass: MergedLoadStoreMotionPass ; CHECK-Os-NEXT: Running pass: GVNPass ; CHECK-Os-NEXT: Running analysis: MemoryDependenceAnalysis @@ -140,6 +146,8 @@ ; CHECK-O-NEXT: Running pass: BDCEPass ; CHECK-O-NEXT: Running analysis: DemandedBitsAnalysis ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O23SZ-NEXT: Running pass: ConnectNoAliasDeclPass on foo +; CHECK-O23SZ-NEXT: Running pass: PropagateAndConvertNoAliasPass on foo ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis ; CHECK-O23SZ-NEXT: Running pass: CorrelatedValuePropagationPass Index: llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll +++ llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll @@ -38,10 +38,12 @@ ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O-NEXT: Running pass: CoroEarlyPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: InstCombinePass on foo @@ -91,9 +93,11 @@ ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -127,7 +131,9 @@ ; CHECK-O-NEXT: Running pass: IndVarSimplifyPass ; CHECK-O-NEXT: Running pass: LoopDeletionPass ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass on foo +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-Os-NEXT: Running pass: MergedLoadStoreMotionPass ; CHECK-Os-NEXT: Running pass: GVNPass ; CHECK-Os-NEXT: Running analysis: MemoryDependenceAnalysis @@ -149,6 +155,8 @@ ; CHECK-O-NEXT: Running pass: BDCEPass ; CHECK-O-NEXT: Running analysis: DemandedBitsAnalysis ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O23SZ-NEXT: Running pass: ConnectNoAliasDeclPass on foo +; CHECK-O23SZ-NEXT: Running pass: PropagateAndConvertNoAliasPass on foo ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis ; CHECK-O23SZ-NEXT: Running pass: CorrelatedValuePropagationPass Index: llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll +++ llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll @@ -37,10 +37,12 @@ ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O-NEXT: Running pass: CoroEarlyPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: OpenMPOptPass @@ -65,8 +67,10 @@ ; CHECK-O123SZ-NEXT: Running analysis: OuterAnalysisManagerProxy ; CHECK-O123SZ-NEXT: Running pass: InlinerPass on (foo) ; CHECK-O123SZ-NEXT: Running pass: InlinerPass on (foo) +; CHECK-O123SZ-NEXT: Running pass: ConnectNoAliasDeclPass on foo ; CHECK-O123SZ-NEXT: Running pass: SROAPass on foo ; CHECK-O123SZ-NEXT: Running pass: EarlyCSEPass on foo +; CHECK-O123SZ-NEXT: Running pass: PropagateAndConvertNoAliasPass on foo ; CHECK-O123SZ-NEXT: Running pass: SimplifyCFGPass on foo ; CHECK-O123SZ-NEXT: Running pass: InstCombinePass on foo ; CHECK-O123SZ-NEXT: Invalidating analysis: InlineAdvisorAnalysis @@ -112,9 +116,11 @@ ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -156,7 +162,9 @@ ; CHECK-O-NEXT: Running pass: IndVarSimplifyPass ; CHECK-O-NEXT: Running pass: LoopDeletionPass ; CHECK-O-NEXT: Running pass: LoopFullUnrollPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass on foo +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-Os-NEXT: Running pass: MergedLoadStoreMotionPass ; CHECK-Os-NEXT: Running pass: GVNPass ; CHECK-Os-NEXT: Running analysis: MemoryDependenceAnalysis @@ -178,6 +186,8 @@ ; CHECK-O-NEXT: Running pass: BDCEPass ; CHECK-O-NEXT: Running analysis: DemandedBitsAnalysis ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O23SZ-NEXT: Running pass: ConnectNoAliasDeclPass on foo +; CHECK-O23SZ-NEXT: Running pass: PropagateAndConvertNoAliasPass on foo ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis ; CHECK-O23SZ-NEXT: Running pass: CorrelatedValuePropagationPass Index: llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll +++ llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll @@ -36,10 +36,12 @@ ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O-NEXT: Running pass: CoroEarlyPass ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass ; CHECK-O-NEXT: Running pass: InstCombinePass on foo @@ -86,9 +88,11 @@ ; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass ; CHECK-O2-NEXT: Running pass: OpenMPOptCGSCCPass ; CHECK-O3-NEXT: Running pass: OpenMPOptCGSCCPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass ; CHECK-O-NEXT: Running pass: EarlyCSEPass ; CHECK-O-NEXT: Running analysis: MemorySSAAnalysis +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-O23SZ-NEXT: Running pass: SpeculativeExecutionPass ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis @@ -121,7 +125,9 @@ ; CHECK-O-NEXT: Running pass: LoopIdiomRecognizePass ; CHECK-O-NEXT: Running pass: IndVarSimplifyPass ; CHECK-O-NEXT: Running pass: LoopDeletionPass +; CHECK-O-NEXT: Running pass: ConnectNoAliasDeclPass ; CHECK-O-NEXT: Running pass: SROAPass on foo +; CHECK-O-NEXT: Running pass: PropagateAndConvertNoAliasPass ; CHECK-Os-NEXT: Running pass: MergedLoadStoreMotionPass ; CHECK-Os-NEXT: Running pass: GVNPass ; CHECK-Os-NEXT: Running analysis: MemoryDependenceAnalysis @@ -143,6 +149,8 @@ ; CHECK-O-NEXT: Running pass: BDCEPass ; CHECK-O-NEXT: Running analysis: DemandedBitsAnalysis ; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O23SZ-NEXT: Running pass: ConnectNoAliasDeclPass on foo +; CHECK-O23SZ-NEXT: Running pass: PropagateAndConvertNoAliasPass on foo ; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass ; CHECK-O23SZ-NEXT: Running analysis: LazyValueAnalysis ; CHECK-O23SZ-NEXT: Running pass: CorrelatedValuePropagationPass Index: llvm/test/Transforms/ConnectNoAliasDecl/basictest.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/ConnectNoAliasDecl/basictest.ll @@ -0,0 +1,179 @@ +; RUN: opt < %s -connect-noaliasdecl -verify -S | FileCheck %s +; RUN: opt < %s -passes=connect-noaliasdecl,verify -S | FileCheck %s + +target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" + + +%struct.FOO = type { i32*, i32*, i32* } + +; Function Attrs: nounwind +define dso_local void @test_01_before(i32** %_p, i32 %c) #0 !noalias !2 { +entry: + %rp = alloca [2 x i32*], align 4 + %other = alloca i32*, align 4 + %local_tmp = alloca i32*, align 4 + %tmp.0 = bitcast [2 x i32*]* %rp to i8* + %.fca.0.gep = getelementptr inbounds [2 x i32*], [2 x i32*]* %rp, i32 0, i32 0 + %.fca.1.gep = getelementptr inbounds [2 x i32*], [2 x i32*]* %rp, i32 0, i32 1 + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp.0) #5, !noalias !5 + %tmp.1 = call i8* @llvm.noalias.decl.p0i8.p0a2p0i32.i32([2 x i32*]* %rp, i32 0, metadata !7) + %tmp.2 = load i32*, i32** %_p, align 4, !tbaa !8, !noalias !5 + store i32* %tmp.2, i32** %.fca.0.gep, align 4, !tbaa !8, !noalias !5 + %arrayinit.element = getelementptr inbounds i32*, i32** %.fca.0.gep, i32 1 + %arrayidx1 = getelementptr inbounds i32*, i32** %_p, i32 1 + %tmp.3 = load i32*, i32** %arrayidx1, align 4, !tbaa !8, !noalias !5 + store i32* %tmp.3, i32** %arrayinit.element, align 4, !tbaa !8, !noalias !5 + %tmp.4 = bitcast i32** %other to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* %tmp.4) #5, !noalias !5 + %arrayidx2 = getelementptr inbounds i32*, i32** %_p, i32 2 + %tmp.5 = load i32*, i32** %arrayidx2, align 4, !tbaa !8, !noalias !5 + store i32* %tmp.5, i32** %other, align 4, !tbaa !8, !noalias !5 + %tobool = icmp ne i32 %c, 0 + %cond = select i1 %tobool, i32** %.fca.0.gep, i32** %other + %tmp.6 = load i32*, i32** %arrayinit.element, align 4, !tbaa !8, !noalias !5 + %through_local_tmp = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %tmp.6, i8* null, i32** %arrayinit.element, i32 0, metadata !2), !tbaa !8, !noalias !5 + %tmp.7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %through_local_tmp, i8* null, i32** %local_tmp, i32 0, metadata !2), !tbaa !8, !noalias !5 + %tmp.8 = load i32, i32* %tmp.7, align 4, !tbaa !12, !noalias !5 + %tmp.9 = load i32*, i32** %.fca.0.gep, align 4, !tbaa !8, !noalias !5 + %tmp.10 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %tmp.9, i8* null, i32** %.fca.0.gep, i32 0, metadata !2), !tbaa !8, !noalias !5 + store i32 %tmp.8, i32* %tmp.10, align 4, !tbaa !12, !noalias !5 + %tmp.11 = load i32*, i32** %cond, align 4, !tbaa !8, !noalias !5 + %tmp.12 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %tmp.11, i8* null, i32** %cond, i32 0, metadata !2), !tbaa !8, !noalias !5 + store i32 42, i32* %tmp.12, align 4, !tbaa !12, !noalias !5 + call void @llvm.lifetime.end.p0i8(i64 4, i8* %tmp.4) #5 + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp.0) #5 + ret void +} + +; CHECK-LABEL: @test_01_before( +; CHECK: %tmp.1 = call i8* @llvm.noalias.decl.p0i8.p0a2p0i32.i32([2 x i32*]* %rp, i32 0, metadata !7) +; CHECK: %through_local_tmp = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %tmp.6, i8* %tmp.1, i32** %arrayinit.element, i32 0, metadata !7), !tbaa !8, !noalias !5 +; CHECK: %tmp.10 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %tmp.9, i8* %tmp.1, i32** %.fca.0.gep, i32 0, metadata !7), !tbaa !8, !noalias !5 +; CHECK: %tmp.12 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %tmp.11, i8* null, i32** %cond, i32 0, metadata !2), !tbaa !8, !noalias !5 +; CHECK-NOT: llvm.noalias + +; Function Attrs: nounwind +define dso_local void @test_02(i32** %_p, i32 %c) #0 !noalias !14 { +entry: + %foo = alloca %struct.FOO, align 4 + %tmp = alloca %struct.FOO, align 4 + %tmp.1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FOOs.i32(%struct.FOO* %foo, i32 0, metadata !17) + %tmp.10 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FOOs.i32(%struct.FOO* %tmp, i32 0, metadata !19) + %tmp.12 = call %struct.FOO* @llvm.noalias.copy.guard.p0s_struct.FOOs.p0i8(%struct.FOO* %foo, i8* null, metadata !21, metadata !14) + %tmp.13 = load %struct.FOO, %struct.FOO* %tmp.12, align 4, !noalias !25 + store %struct.FOO %tmp.13, %struct.FOO* %tmp, !noalias !25 + ret void +} + +; CHECK-LABEL: @test_02( +; CHECK: %tmp.1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FOOs.i32(%struct.FOO* %foo, i32 0, metadata !17) +; CHECK: %tmp.10 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FOOs.i32(%struct.FOO* %tmp, i32 0, metadata !19) +; CHECK: %tmp.12 = call %struct.FOO* @llvm.noalias.copy.guard.p0s_struct.FOOs.p0i8(%struct.FOO* %foo, i8* %tmp.1, metadata !21, metadata !17) +; CHECK-NOT: llvm.noalias + +; Function Attrs: nounwind +define dso_local void @test_01_after(i32** %_p, i32 %c) #0 !noalias !2 { +entry: + %rp = alloca [2 x i32*], align 4 + %local_tmp = alloca i32*, align 4 + %other = alloca i32*, align 4 + %.fca.0.gep = getelementptr inbounds [2 x i32*], [2 x i32*]* %rp, i32 0, i32 0 + %.fca.1.gep = getelementptr inbounds [2 x i32*], [2 x i32*]* %rp, i32 0, i32 1 + %tmp.0 = bitcast [2 x i32*]* %rp to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp.0) #5, !noalias !5 + %tmp.1 = call i8* @llvm.noalias.decl.p0i8.p0a2p0i32.i32([2 x i32*]* %rp, i32 0, metadata !7) + %tmp.2 = load i32*, i32** %_p, ptr_provenance i32** undef, align 4, !tbaa !8, !noalias !5 + store i32* %tmp.2, i32** %.fca.0.gep, ptr_provenance i32** undef, align 4, !tbaa !8, !noalias !5 + %arrayinit.element = getelementptr inbounds i32*, i32** %.fca.0.gep, i32 1 + %arrayidx1 = getelementptr inbounds i32*, i32** %_p, i32 1 + %tmp.3 = load i32*, i32** %arrayidx1, ptr_provenance i32** undef, align 4, !tbaa !8, !noalias !5 + store i32* %tmp.3, i32** %arrayinit.element, ptr_provenance i32** undef, align 4, !tbaa !8, !noalias !5 + %tmp.4 = bitcast i32** %other to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* %tmp.4) #5, !noalias !5 + %arrayidx2 = getelementptr inbounds i32*, i32** %_p, i32 2 + %tmp.5 = load i32*, i32** %arrayidx2, ptr_provenance i32** undef, align 4, !tbaa !8, !noalias !5 + store i32* %tmp.5, i32** %other, ptr_provenance i32** undef, align 4, !tbaa !8, !noalias !5 + %tobool = icmp ne i32 %c, 0 + %cond = select i1 %tobool, i32** %.fca.0.gep, i32** %other + %tmp.6 = load i32*, i32** %arrayinit.element, ptr_provenance i32** undef, align 4, !tbaa !8, !noalias !5 + %through_local_tmp = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %tmp.6, i8* null, i32** %arrayinit.element, i32** undef, i32 0, metadata !2), !tbaa !8, !noalias !5 + %tmp.7 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %through_local_tmp, i8* null, i32** %local_tmp, i32** undef, i32 0, metadata !2), !tbaa !8, !noalias !5 + %tmp.8 = load i32, i32* %tmp.6, ptr_provenance i32* %tmp.7, align 4, !tbaa !12, !noalias !5 + %tmp.9 = load i32*, i32** %.fca.0.gep, ptr_provenance i32** undef, align 4, !tbaa !8, !noalias !5 + %tmp.10 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %tmp.9, i8* null, i32** %.fca.0.gep, i32** undef, i32 0, metadata !2), !tbaa !8, !noalias !5 + store i32 %tmp.8, i32* %tmp.9, ptr_provenance i32* %tmp.10, align 4, !tbaa !12, !noalias !5 + %tmp.11 = load i32*, i32** %cond, ptr_provenance i32** undef, align 4, !tbaa !8, !noalias !5 + %tmp.12 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %tmp.11, i8* null, i32** %cond, i32** undef, i32 0, metadata !2), !tbaa !8, !noalias !5 + store i32 42, i32* %tmp.11, ptr_provenance i32* %tmp.12, align 4, !tbaa !12, !noalias !5 + call void @llvm.lifetime.end.p0i8(i64 4, i8* %tmp.4) #5 + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp.0) #5 + ret void +} + +; CHECK-LABEL: @test_01_after( +; CHECK: %tmp.1 = call i8* @llvm.noalias.decl.p0i8.p0a2p0i32.i32([2 x i32*]* %rp, i32 0, metadata !7) +; CHECK: %through_local_tmp = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %tmp.6, i8* %tmp.1, i32** %arrayinit.element, i32** undef, i32 0, metadata !7), !tbaa !8, !noalias !5 +; CHECK: %tmp.10 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %tmp.9, i8* %tmp.1, i32** %.fca.0.gep, i32** undef, i32 0, metadata !7), !tbaa !8, !noalias !5 +; CHECK: %tmp.12 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %tmp.11, i8* null, i32** %cond, i32** undef, i32 0, metadata !2), !tbaa !8, !noalias !5 +; CHECK-NOT: llvm.noalias + +; CHECK: declare + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0a2p0i32.i32([2 x i32*]*, i32, metadata) #1 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0s_struct.FOOs.i32(%struct.FOO*, i32, metadata) #1 + +; Function Attrs: nounwind readnone +declare %struct.FOO* @llvm.noalias.copy.guard.p0s_struct.FOOs.p0i8(%struct.FOO*, i8*, metadata, metadata) #3 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #4 + + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { argmemonly nounwind speculatable } +attributes #3 = { nounwind readnone } +attributes #4 = { nounwind readnone speculatable } +attributes #5 = { nounwind } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test_01: unknown scope"} +!4 = distinct !{!4, !"test_01"} +!5 = !{!6, !3} +!6 = distinct !{!6, !4, !"test_01: rp"} +!7 = !{!6} +!8 = !{!9, !9, i64 0, i64 4} +!9 = !{!10, i64 4, !"any pointer"} +!10 = !{!11, i64 1, !"omnipotent char"} +!11 = !{!"Simple C/C++ TBAA"} +!12 = !{!13, !13, i64 0, i64 4} +!13 = !{!10, i64 4, !"int"} +!14 = !{!15} +!15 = distinct !{!15, !16, !"test_02: unknown scope"} +!16 = distinct !{!16, !"test_02"} +!17 = !{!18} +!18 = distinct !{!18, !16, !"test_02: foo"} +!19 = !{!20} +!20 = distinct !{!20, !16, !"test_02: tmp"} +!21 = !{!22, !23, !24} +!22 = !{i64 -1, i64 0} +!23 = !{i64 -1, i64 1} +!24 = !{i64 -1, i64 2} +!25 = !{!20, !18, !15} Index: llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll +++ llvm/test/Transforms/Coroutines/coro-retcon-resume-values.ll @@ -44,17 +44,21 @@ ; CHECK-NEXT: store i8* [[TMP1]], i8** [[TMP0]], align 8 ; CHECK-NEXT: [[N_SPILL_ADDR_I:%.*]] = bitcast i8* [[TMP1]] to i32* ; CHECK-NEXT: store i32 1, i32* [[N_SPILL_ADDR_I]], align 4 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]]) -; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8** [[TMP0]] to %f.Frame** -; CHECK-NEXT: [[FRAMEPTR_I:%.*]] = load %f.Frame*, %f.Frame** [[TMP2]], align 8, !alias.scope !0 +; CHECK-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META0:![0-9]+]]) +; CHECK-NEXT: [[TMP3:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[DOTSUB]], i8* [[TMP2]], i8** null, i8** undef, i64 0, metadata [[META0]]), !noalias !0 +; CHECK-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP3]] to %f.Frame** +; CHECK-NEXT: [[TMP5:%.*]] = bitcast i8** [[TMP0]] to %f.Frame** +; CHECK-NEXT: [[FRAMEPTR_I:%.*]] = load %f.Frame*, %f.Frame** [[TMP5]], ptr_provenance %f.Frame** [[TMP4]], align 8, !noalias !0 ; CHECK-NEXT: [[N_RELOAD_ADDR9_I:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], %f.Frame* [[FRAMEPTR_I]], i64 0, i32 0 ; CHECK-NEXT: [[N_RELOAD10_I:%.*]] = load i32, i32* [[N_RELOAD_ADDR9_I]], align 4, !noalias !0 ; CHECK-NEXT: [[N_VAL3_SPILL_ADDR_I:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR_I]], i64 0, i32 1 ; CHECK-NEXT: store i32 [[N_RELOAD10_I]], i32* [[N_VAL3_SPILL_ADDR_I]], align 4, !noalias !0 ; CHECK-NEXT: [[INPUT_SPILL_ADDR_I:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR_I]], i64 0, i32 2 ; CHECK-NEXT: store i32 2, i32* [[INPUT_SPILL_ADDR_I]], align 4, !noalias !0 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -; CHECK-NEXT: [[FRAMEPTR_I1:%.*]] = load %f.Frame*, %f.Frame** [[TMP2]], align 8, !alias.scope !3 +; CHECK-NEXT: [[TMP6:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META3:![0-9]+]]) +; CHECK-NEXT: [[TMP7:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[DOTSUB]], i8* [[TMP6]], i8** null, i8** undef, i64 0, metadata [[META3]]), !noalias !3 +; CHECK-NEXT: [[TMP8:%.*]] = bitcast i8* [[TMP7]] to %f.Frame** +; CHECK-NEXT: [[FRAMEPTR_I1:%.*]] = load %f.Frame*, %f.Frame** [[TMP5]], ptr_provenance %f.Frame** [[TMP8]], align 8, !noalias !3 ; CHECK-NEXT: [[INPUT_RELOAD_ADDR_I:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR_I1]], i64 0, i32 2 ; CHECK-NEXT: [[INPUT_RELOAD_I:%.*]] = load i32, i32* [[INPUT_RELOAD_ADDR_I]], align 4, !noalias !3 ; CHECK-NEXT: [[N_VAL3_RELOAD_ADDR_I:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR_I1]], i64 0, i32 1 @@ -62,16 +66,18 @@ ; CHECK-NEXT: [[SUM8_I:%.*]] = add i32 [[N_VAL3_RELOAD_I]], [[INPUT_RELOAD_I]] ; CHECK-NEXT: store i32 [[SUM8_I]], i32* [[N_VAL3_RELOAD_ADDR_I]], align 4, !noalias !3 ; CHECK-NEXT: store i32 4, i32* [[INPUT_RELOAD_ADDR_I]], align 4, !noalias !3 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) -; CHECK-NEXT: [[FRAMEPTR_I4:%.*]] = load %f.Frame*, %f.Frame** [[TMP2]], align 8, !alias.scope !6 +; CHECK-NEXT: [[TMP9:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META6:![0-9]+]]) +; CHECK-NEXT: [[TMP10:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[DOTSUB]], i8* [[TMP9]], i8** null, i8** undef, i64 0, metadata [[META6]]), !noalias !6 +; CHECK-NEXT: [[TMP11:%.*]] = bitcast i8* [[TMP10]] to %f.Frame** +; CHECK-NEXT: [[FRAMEPTR_I4:%.*]] = load %f.Frame*, %f.Frame** [[TMP5]], ptr_provenance %f.Frame** [[TMP11]], align 8, !noalias !6 ; CHECK-NEXT: [[INPUT_RELOAD_ADDR13_I:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR_I4]], i64 0, i32 2 ; CHECK-NEXT: [[INPUT_RELOAD14_I:%.*]] = load i32, i32* [[INPUT_RELOAD_ADDR13_I]], align 4, !noalias !6 ; CHECK-NEXT: [[N_VAL3_RELOAD_ADDR11_I:%.*]] = getelementptr inbounds [[F_FRAME]], %f.Frame* [[FRAMEPTR_I4]], i64 0, i32 1 ; CHECK-NEXT: [[N_VAL3_RELOAD12_I:%.*]] = load i32, i32* [[N_VAL3_RELOAD_ADDR11_I]], align 4, !noalias !6 ; CHECK-NEXT: [[SUM7_I:%.*]] = add i32 [[N_VAL3_RELOAD12_I]], [[INPUT_RELOAD14_I]] ; CHECK-NEXT: call void @print(i32 [[SUM7_I]]), !noalias !6 -; CHECK-NEXT: [[TMP3:%.*]] = bitcast %f.Frame* [[FRAMEPTR_I4]] to i8* -; CHECK-NEXT: call void @deallocate(i8* [[TMP3]]), !noalias !6 +; CHECK-NEXT: [[TMP12:%.*]] = bitcast %f.Frame* [[FRAMEPTR_I4]] to i8* +; CHECK-NEXT: call void @deallocate(i8* [[TMP12]]), !noalias !6 ; CHECK-NEXT: ret i32 0 ; entry: Index: llvm/test/Transforms/Coroutines/coro-retcon-value.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-retcon-value.ll +++ llvm/test/Transforms/Coroutines/coro-retcon-value.ll @@ -40,14 +40,20 @@ ; CHECK-NEXT: [[N_VAL_SPILL_ADDR_I:%.*]] = bitcast [8 x i8]* [[TMP0]] to i32* ; CHECK-NEXT: store i32 4, i32* [[N_VAL_SPILL_ADDR_I]], align 4 ; CHECK-NEXT: call void @print(i32 4) -; CHECK-NEXT: [[N_VAL_RELOAD_I:%.*]] = load i32, i32* [[N_VAL_SPILL_ADDR_I]], align 4, !alias.scope !0 +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META0:![0-9]+]]) +; CHECK-NEXT: [[TMP2:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[DOTSUB]], i8* [[TMP1]], i8** null, i8** undef, i64 0, metadata [[META0]]), !noalias !0 +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32* +; CHECK-NEXT: [[N_VAL_RELOAD_I:%.*]] = load i32, i32* [[N_VAL_SPILL_ADDR_I]], ptr_provenance i32* [[TMP3]], align 4, !noalias !0 ; CHECK-NEXT: [[INC_I:%.*]] = add i32 [[N_VAL_RELOAD_I]], 1 -; CHECK-NEXT: store i32 [[INC_I]], i32* [[N_VAL_SPILL_ADDR_I]], align 4, !alias.scope !0 +; CHECK-NEXT: store i32 [[INC_I]], i32* [[N_VAL_SPILL_ADDR_I]], ptr_provenance i32* [[TMP3]], align 4, !noalias !0 ; CHECK-NEXT: call void @print(i32 [[INC_I]]) -; CHECK-NEXT: [[N_VAL_RELOAD_I3:%.*]] = load i32, i32* [[N_VAL_SPILL_ADDR_I]], align 4, !alias.scope !3 -; CHECK-NEXT: [[INC_I4:%.*]] = add i32 [[N_VAL_RELOAD_I3]], 1 -; CHECK-NEXT: store i32 [[INC_I4]], i32* [[N_VAL_SPILL_ADDR_I]], align 4, !alias.scope !3 -; CHECK-NEXT: call void @print(i32 [[INC_I4]]) +; CHECK-NEXT: [[TMP4:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META3:![0-9]+]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[DOTSUB]], i8* [[TMP4]], i8** null, i8** undef, i64 0, metadata [[META3]]), !noalias !3 +; CHECK-NEXT: [[TMP6:%.*]] = bitcast i8* [[TMP5]] to i32* +; CHECK-NEXT: [[N_VAL_RELOAD_I1:%.*]] = load i32, i32* [[N_VAL_SPILL_ADDR_I]], ptr_provenance i32* [[TMP6]], align 4, !noalias !3 +; CHECK-NEXT: [[INC_I2:%.*]] = add i32 [[N_VAL_RELOAD_I1]], 1 +; CHECK-NEXT: store i32 [[INC_I2]], i32* [[N_VAL_SPILL_ADDR_I]], ptr_provenance i32* [[TMP6]], align 4, !noalias !3 +; CHECK-NEXT: call void @print(i32 [[INC_I2]]) ; CHECK-NEXT: ret i32 0 ; entry: Index: llvm/test/Transforms/Coroutines/coro-retcon.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-retcon.ll +++ llvm/test/Transforms/Coroutines/coro-retcon.ll @@ -40,15 +40,19 @@ ; CHECK-NEXT: [[N_VAL_SPILL_ADDR_I:%.*]] = bitcast [8 x i8]* [[TMP0]] to i32* ; CHECK-NEXT: store i32 4, i32* [[N_VAL_SPILL_ADDR_I]], align 4 ; CHECK-NEXT: call void @print(i32 4) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]]) -; CHECK-NEXT: [[N_VAL_RELOAD_I:%.*]] = load i32, i32* [[N_VAL_SPILL_ADDR_I]], align 4, !alias.scope !0 +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META0:![0-9]+]]) +; CHECK-NEXT: [[TMP2:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[DOTSUB]], i8* [[TMP1]], i8** null, i8** undef, i64 0, metadata [[META0]]), !noalias !0 +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32* +; CHECK-NEXT: [[N_VAL_RELOAD_I:%.*]] = load i32, i32* [[N_VAL_SPILL_ADDR_I]], ptr_provenance i32* [[TMP3]], align 4, !noalias !0 ; CHECK-NEXT: [[INC_I:%.*]] = add i32 [[N_VAL_RELOAD_I]], 1 -; CHECK-NEXT: store i32 [[INC_I]], i32* [[N_VAL_SPILL_ADDR_I]], align 4, !alias.scope !0 +; CHECK-NEXT: store i32 [[INC_I]], i32* [[N_VAL_SPILL_ADDR_I]], ptr_provenance i32* [[TMP3]], align 4, !noalias !0 ; CHECK-NEXT: call void @print(i32 [[INC_I]]), !noalias !0 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -; CHECK-NEXT: [[N_VAL_RELOAD_I3:%.*]] = load i32, i32* [[N_VAL_SPILL_ADDR_I]], align 4, !alias.scope !3 -; CHECK-NEXT: [[INC_I4:%.*]] = add i32 [[N_VAL_RELOAD_I3]], 1 -; CHECK-NEXT: call void @print(i32 [[INC_I4]]), !noalias !3 +; CHECK-NEXT: [[TMP4:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META3:![0-9]+]]) +; CHECK-NEXT: [[TMP5:%.*]] = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i64(i8* nonnull [[DOTSUB]], i8* [[TMP4]], i8** null, i8** undef, i64 0, metadata [[META3]]), !noalias !3 +; CHECK-NEXT: [[TMP6:%.*]] = bitcast i8* [[TMP5]] to i32* +; CHECK-NEXT: [[N_VAL_RELOAD_I1:%.*]] = load i32, i32* [[N_VAL_SPILL_ADDR_I]], ptr_provenance i32* [[TMP6]], align 4, !noalias !3 +; CHECK-NEXT: [[INC_I2:%.*]] = add i32 [[N_VAL_RELOAD_I1]], 1 +; CHECK-NEXT: call void @print(i32 [[INC_I2]]), !noalias !3 ; CHECK-NEXT: ret i32 0 ; entry: Index: llvm/test/Transforms/DeadArgElim/noalias.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/DeadArgElim/noalias.ll @@ -0,0 +1,26 @@ +; RUN: opt -deadargelim -S < %s | FileCheck %s + +; Checks if !noalias metadata is correct in deadargelim. + +define void @caller() #0 { +; CHECK: call void @test_vararg(), !noalias ![[NA:[0-9]]] +; CHECK: call void @test(), !noalias ![[NA]] + call void (i32, ...) @test_vararg(i32 1), !noalias !0 + call void @test(i32 1), !noalias !0 + ret void +} + +define internal void @test_vararg(i32, ...) #1 { + ret void +} + +define internal void @test(i32 %a) #1 { + ret void +} + +; CHECK:![[NA]] = !{![[NA2:[0-9]]]} +; CHECK:![[NA2]] = distinct !{![[NA2]], ![[NA3:[0-9]]], !"the var"} +; CHECK:![[NA3]] = distinct !{![[NA3]], !"Domain"} +!0 = !{!1} +!1 = distinct !{!1, !2, !"the var"} +!2 = distinct !{!2, !"Domain"} Index: llvm/test/Transforms/EarlyCSE/basic.ll =================================================================== --- llvm/test/Transforms/EarlyCSE/basic.ll +++ llvm/test/Transforms/EarlyCSE/basic.ll @@ -54,6 +54,26 @@ ; CHECK: ret i32 0 } +; CHECK-LABEL: @test2b( +define i32 @test2b(i32 *%P, i1 %b) { + %V1 = load i32, i32* %P + call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i32(i8* undef, i8* null, i8** null, i32 0, metadata !1) + %V2 = load i32, i32* %P + %Diff = sub i32 %V1, %V2 + ret i32 %Diff + ; CHECK: ret i32 0 +} + +; CHECK-LABEL: @test2c( +define i32 @test2c(i32 *%P, i1 %b) { + %V1 = load i32, i32* %P + call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* undef, i8* null, i8** null, i8** null, i32 0, metadata !1) + %V2 = load i32, i32* %P + %Diff = sub i32 %V1, %V2 + ret i32 %Diff + ; CHECK: ret i32 0 +} + ;; Cross block load value numbering. ; CHECK-LABEL: @test3( define i32 @test3(i32 *%P, i1 %Cond) { @@ -134,6 +154,24 @@ ; CHECK: ret i32 42 } +; CHECK-LABEL: @test6b( +define i32 @test6b(i32 *%P, i1 %b) { + store i32 42, i32* %P + call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i32(i8* undef, i8* null, i8** null, i32 0, metadata !1) + %V1 = load i32, i32* %P + ret i32 %V1 + ; CHECK: ret i32 42 +} + +; CHECK-LABEL: @test6c( +define i32 @test6c(i32 *%P, i1 %b) { + store i32 42, i32* %P + call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* undef, i8* null, i8** null, i8** null, i32 0, metadata !1) + %V1 = load i32, i32* %P + ret i32 %V1 + ; CHECK: ret i32 42 +} + ;; Trivial dead store elimination. ; CHECK-LABEL: @test7( define void @test7(i32 *%P) { @@ -302,3 +340,9 @@ %and = and i1 %b, %c ret i1 %and } + +declare i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i32(i8*, i8*, i8**, i32, metadata ) nounwind +declare i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8*, i8*, i8**, i8**, i32, metadata ) nounwind + +!0 = !{!0, !"some domain"} +!1 = !{!1, !0, !"some scope"} Index: llvm/test/Transforms/FunctionAttrs/nocapture.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/nocapture.ll +++ llvm/test/Transforms/FunctionAttrs/nocapture.ll @@ -106,6 +106,40 @@ ret i32 %val } +; FNATTR: define i32 @nc1a(i32* %q, i32* nocapture %p, i1 %b) +define i32 @nc1a(i32* %q, i32* %p, i1 %b) { +e: + %pa = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %p, i8* null, i32** null, i32 0, metadata !1) + br label %l +l: + %x = phi i32* [ %pa, %e ] + %y = phi i32* [ %q, %e ] + %tmp = bitcast i32* %x to i32* ; [#uses=2] + %tmp2 = select i1 %b, i32* %tmp, i32* %y + %val = load i32, i32* %tmp2 ; [#uses=1] + store i32 0, i32* %tmp + store i32* %y, i32** @g + ret i32 %val +} + +; FNATTR: define i32 @nc1b(i32* %q, i32* nocapture %p, i1 %b) +define i32 @nc1b(i32* %q, i32* %p, i1 %b) { +e: + %prov.p = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %p, i8* null, i32** null, i32** null, i32 0, metadata !1) + br label %l +l: + %x = phi i32* [ %p, %e ] + %prov.x = phi i32* [ %prov.p, %e ] + %y = phi i32* [ %q, %e ] + %tmp = bitcast i32* %x to i32* ; [#uses=2] + %tmp2 = select i1 %b, i32* %tmp, i32* %y + %prov.tmp2 = select i1 %b, i32* %prov.x, i32* %y + %val = load i32, i32* %tmp2 ; [#uses=1] + store i32 0, i32* %tmp, ptr_provenance i32* %prov.tmp2 + store i32* %y, i32** @g + ret i32 %val +} + ; FNATTR: define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* nocapture %p, i1 %b) define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* %p, i1 %b) { e: @@ -319,3 +353,9 @@ declare i8* @llvm.launder.invariant.group.p0i8(i8*) declare i8* @llvm.strip.invariant.group.p0i8(i8*) + +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata ) nounwind +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata ) nounwind + +!0 = !{!0, !"some domain"} +!1 = !{!1, !0, !"some scope"} Index: llvm/test/Transforms/FunctionAttrs/nonnull.ll =================================================================== --- llvm/test/Transforms/FunctionAttrs/nonnull.ll +++ llvm/test/Transforms/FunctionAttrs/nonnull.ll @@ -779,5 +779,15 @@ br i1 %11, label %7, label %8 } +; Return a pointer trivially nonnull (argument attribute) through a llvm.noalias.arg.guard +; FNATTR: define nonnull i8* @test_noalias_arg_guard +define i8* @test_noalias_arg_guard(i8* nonnull %p) { + %ret = tail call i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8* %p, i8* %p) + ret i8* %p +} + +; Function Attrs: nounwind readnone +declare i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8*, i8*) nounwind readnone + attributes #0 = { null_pointer_is_valid } attributes #1 = { nounwind willreturn} Index: llvm/test/Transforms/Inline/launder.invariant.group.ll =================================================================== --- llvm/test/Transforms/Inline/launder.invariant.group.ll +++ llvm/test/Transforms/Inline/launder.invariant.group.ll @@ -1,6 +1,10 @@ -; RUN: opt -S -inline < %s | FileCheck %s -; RUN: opt -S -O3 < %s | FileCheck %s -; RUN: opt -S -inline -inline-threshold=1 < %s | FileCheck %s +; RUN: opt -S -inline --use-noalias-intrinsic-during-inlining=scopes < %s | FileCheck %s --check-prefixes=CHECK,CHECK_SCOPED +; RUN: opt -S -O3 --use-noalias-intrinsic-during-inlining=scopes < %s | FileCheck %s --check-prefixes=CHECK,CHECK_SCOPED,CHECK_OPT +; RUN: opt -S -inline -inline-threshold=1 --use-noalias-intrinsic-during-inlining=scopes < %s | FileCheck %s --check-prefixes=CHECK,CHECK_SCOPED + +; RUN: opt -S -inline --use-noalias-intrinsic-during-inlining=full < %s | FileCheck %s --check-prefixes=CHECK,CHECK_NOALIAS +; RUN: opt -S -O3 --use-noalias-intrinsic-during-inlining=full < %s | FileCheck %s --check-prefixes=CHECK,CHECK_PROVENANCE,CHECK_OPT +; RUN: opt -S -inline -inline-threshold=1 --use-noalias-intrinsic-during-inlining=full < %s | FileCheck %s --check-prefixes=CHECK,CHECK_NOALIAS %struct.A = type <{ i32 (...)**, i32, [4 x i8] }> @@ -9,7 +13,7 @@ ; sometimes it would be considered noalias. ; CHECK-LABEL: define i32 @bar(%struct.A* noalias define i32 @bar(%struct.A* noalias) { -; CHECK-NOT: noalias +; CHECK_SCOPED-NOT: noalias %2 = bitcast %struct.A* %0 to i8* %3 = call i8* @llvm.launder.invariant.group.p0i8(i8* %2) %4 = getelementptr inbounds i8, i8* %3, i64 8 @@ -22,10 +26,24 @@ ; CHECK-LABEL: define i32 @foo(%struct.A* noalias define i32 @foo(%struct.A* noalias) { - ; CHECK-NOT: call i32 @bar( - ; CHECK-NOT: !noalias + ; CHECK_SCOPED-NOT: call i32 @bar( + ; CHECK_SCOPED-NOT: !noalias + + ; CHECK_NOALIAS-NOT: call i32 @bar( + ; CHECK_NOALIAS: @llvm.noalias.decl.p0 + ; CHECK_NOALIAS-NEXT: @llvm.noalias.p0 + ; CHECK_NOALIAS-NOT: call i32 @bar( + + ; CHECK_PROVENANCE-NOT: call i32 @bar( + ; CHECK_PROVENANCE: @llvm.noalias.decl.p0 + ; CHECK_PROVENANCE-NEXT: @llvm.provenance.noalias.p0 + ; CHECK_PROVENANCE-NOT: call i32 @bar( + ; CHECK_PROVENANCE: @llvm.noalias.arg.guard.p0 + ; CHECK_PROVENANCE-NOT: call i32 @bar( %2 = tail call i32 @bar(%struct.A* %0) ret i32 %2 + + ; CHECK_OPT: ret i32 42 } Index: llvm/test/Transforms/Inline/noalias-calls-always.ll =================================================================== --- llvm/test/Transforms/Inline/noalias-calls-always.ll +++ llvm/test/Transforms/Inline/noalias-calls-always.ll @@ -31,14 +31,16 @@ ; CHECK-LABEL: @foo( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META0:metadata !.*]]) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META3:metadata !.*]]) +; CHECK-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META0:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[A:%.*]], i8* [[TMP0]], i8** null, i64 0, metadata [[META0]]), !noalias !3 +; CHECK-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META5:![0-9]+]]) +; CHECK-NEXT: [[TMP3:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[C:%.*]], i8* [[TMP2]], i8** null, i64 0, metadata [[META5]]), !noalias !3 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A:%.*]], i8* align 16 [[B:%.*]], i64 16, i1 false) [[ATTR4:#.*]], !noalias !3 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C:%.*]], i64 16, i1 false) [[ATTR4]], !noalias !0 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !alias.scope !5 -; CHECK-NEXT: call void @hey() [[ATTR4]], !noalias !5 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !noalias !0 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[B:%.*]], i64 16, i1 false) #[[ATTR6:[0-9]+]], !noalias !3 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !3 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !3 +; CHECK-NEXT: call void @hey() #[[ATTR6]], !noalias !3 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !3 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) ; CHECK-NEXT: ret void ; @@ -72,14 +74,16 @@ ; CHECK-LABEL: @foo_cs( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META6:metadata !.*]]) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META9:metadata !.*]]) +; CHECK-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META6:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[A:%.*]], i8* [[TMP0]], i8** null, i64 0, metadata [[META6]]), !noalias !9 +; CHECK-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +; CHECK-NEXT: [[TMP3:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[C:%.*]], i8* [[TMP2]], i8** null, i64 0, metadata [[META11]]), !noalias !9 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A:%.*]], i8* align 16 [[B:%.*]], i64 16, i1 false) [[ATTR4]], !noalias !9 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C:%.*]], i64 16, i1 false) [[ATTR4]], !noalias !6 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !alias.scope !11 -; CHECK-NEXT: call void @hey() [[ATTR4]], !noalias !11 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR4]], !noalias !6 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[B:%.*]], i64 16, i1 false) #[[ATTR6]], !noalias !9 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !9 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !9 +; CHECK-NEXT: call void @hey() #[[ATTR6]], !noalias !9 +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR6]], !noalias !9 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) ; CHECK-NEXT: ret void ; @@ -95,13 +99,12 @@ ; CHECK: !0 = !{!1} ; CHECK: !1 = distinct !{!1, !2, !"hello: %a"} ; CHECK: !2 = distinct !{!2, !"hello"} -; CHECK: !3 = !{!4} +; CHECK: !3 = !{!1, !4} ; CHECK: !4 = distinct !{!4, !2, !"hello: %c"} -; CHECK: !5 = !{!1, !4} - +; CHECK: !5 = !{!4} ; CHECK: !6 = !{!7} ; CHECK: !7 = distinct !{!7, !8, !"hello_cs: %a"} ; CHECK: !8 = distinct !{!8, !"hello_cs"} -; CHECK: !9 = !{!10} +; CHECK: !9 = !{!7, !10} ; CHECK: !10 = distinct !{!10, !8, !"hello_cs: %c"} -; CHECK: !11 = !{!7, !10} +; CHECK: !11 = !{!10} Index: llvm/test/Transforms/Inline/noalias-calls.ll =================================================================== --- llvm/test/Transforms/Inline/noalias-calls.ll +++ llvm/test/Transforms/Inline/noalias-calls.ll @@ -1,15 +1,19 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature -; RUN: opt -basic-aa -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s -; RUN: opt -aa-pipeline=basic-aa -passes=inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s +; RUN: opt -basic-aa -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=none -S < %s | FileCheck %s -check-prefixes=CHECK,NONE +; RUN: opt -basic-aa -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s -check-prefixes=CHECK,SCOPES +; RUN: opt -basic-aa -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=full -S < %s | FileCheck %s -check-prefixes=CHECK,FULL +; RUN: opt -aa-pipeline=basic-aa -passes=inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=none -S < %s | FileCheck %s -check-prefixes=CHECK,NONE +; RUN: opt -aa-pipeline=basic-aa -passes=inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s -check-prefixes=CHECK,SCOPES +; RUN: opt -aa-pipeline=basic-aa -passes=inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=full -S < %s | FileCheck %s -check-prefixes=CHECK,FULL target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1) #0 -declare void @hey() #0 +declare void @hey() #1 define void @hello(i8* noalias nocapture %a, i8* noalias nocapture readonly %c, i8* nocapture %b) #1 { ; CHECK-LABEL: define {{[^@]+}}@hello -; CHECK-SAME: (i8* noalias nocapture [[A:%.*]], i8* noalias nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) [[ATTR1:#.*]] { +; CHECK-SAME: (i8* noalias nocapture [[A:%.*]], i8* noalias nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) #[[ATTR1:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L:%.*]] = alloca i8, i32 512, align 1 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) @@ -30,20 +34,50 @@ } define void @foo(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 { -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) [[ATTR2:#.*]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META0:metadata !.*]]) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META3:metadata !.*]]) -; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) [[ATTR2]], !noalias !3 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !noalias !0 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !alias.scope !5 -; CHECK-NEXT: call void @hey() [[ATTR2]], !noalias !5 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !noalias !0 -; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) -; CHECK-NEXT: ret void +; NONE-LABEL: define {{[^@]+}}@foo +; NONE-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) #[[ATTR2:[0-9]+]] { +; NONE-NEXT: entry: +; NONE-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 +; NONE-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) +; NONE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) #[[ATTR2]] +; NONE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]] +; NONE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]] +; NONE-NEXT: call void @hey() #[[ATTR2]] +; NONE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]] +; NONE-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) +; NONE-NEXT: ret void +; +; SCOPES-LABEL: define {{[^@]+}}@foo +; SCOPES-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) #[[ATTR2:[0-9]+]] { +; SCOPES-NEXT: entry: +; SCOPES-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]]) +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) +; SCOPES-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) +; SCOPES-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) #[[ATTR2]], !noalias !3 +; SCOPES-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]], !noalias !0 +; SCOPES-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]], !alias.scope !5 +; SCOPES-NEXT: call void @hey() #[[ATTR2]], !noalias !5 +; SCOPES-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]], !noalias !0 +; SCOPES-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) +; SCOPES-NEXT: ret void +; +; FULL-LABEL: define {{[^@]+}}@foo +; FULL-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) #[[ATTR2:[0-9]+]] { +; FULL-NEXT: entry: +; FULL-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 +; FULL-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META0:![0-9]+]]) +; FULL-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[A]], i8* [[TMP0]], i8** null, i64 0, metadata [[META0]]), !noalias !3 +; FULL-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META5:![0-9]+]]) +; FULL-NEXT: [[TMP3:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[C]], i8* [[TMP2]], i8** null, i64 0, metadata [[META5]]), !noalias !3 +; FULL-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) +; FULL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[B]], i64 16, i1 false) #[[ATTR2]], !noalias !3 +; FULL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR2]], !noalias !3 +; FULL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR2]], !noalias !3 +; FULL-NEXT: call void @hey() #[[ATTR2]], !noalias !3 +; FULL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR2]], !noalias !3 +; FULL-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) +; FULL-NEXT: ret void ; entry: tail call void @hello(i8* %a, i8* %c, i8* %b) @@ -52,7 +86,7 @@ define void @hello_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #1 { ; CHECK-LABEL: define {{[^@]+}}@hello_cs -; CHECK-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) [[ATTR1]] { +; CHECK-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) #[[ATTR1]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[L:%.*]] = alloca i8, i32 512, align 1 ; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) @@ -73,20 +107,50 @@ } define void @foo_cs(i8* nocapture %a, i8* nocapture readonly %c, i8* nocapture %b) #2 { -; CHECK-LABEL: define {{[^@]+}}@foo_cs -; CHECK-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) [[ATTR2]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META6:metadata !.*]]) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl([[META9:metadata !.*]]) -; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) [[ATTR2]], !noalias !9 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !noalias !6 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !alias.scope !11 -; CHECK-NEXT: call void @hey() [[ATTR2]], !noalias !11 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) [[ATTR2]], !noalias !6 -; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) -; CHECK-NEXT: ret void +; NONE-LABEL: define {{[^@]+}}@foo_cs +; NONE-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) #[[ATTR2]] { +; NONE-NEXT: entry: +; NONE-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 +; NONE-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) +; NONE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) #[[ATTR2]] +; NONE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]] +; NONE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]] +; NONE-NEXT: call void @hey() #[[ATTR2]] +; NONE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]] +; NONE-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) +; NONE-NEXT: ret void +; +; SCOPES-LABEL: define {{[^@]+}}@foo_cs +; SCOPES-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) #[[ATTR2]] { +; SCOPES-NEXT: entry: +; SCOPES-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META9:![0-9]+]]) +; SCOPES-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) +; SCOPES-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[B]], i64 16, i1 false) #[[ATTR2]], !noalias !9 +; SCOPES-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]], !noalias !6 +; SCOPES-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[A]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]], !alias.scope !11 +; SCOPES-NEXT: call void @hey() #[[ATTR2]], !noalias !11 +; SCOPES-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[C]], i64 16, i1 false) #[[ATTR2]], !noalias !6 +; SCOPES-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) +; SCOPES-NEXT: ret void +; +; FULL-LABEL: define {{[^@]+}}@foo_cs +; FULL-SAME: (i8* nocapture [[A:%.*]], i8* nocapture readonly [[C:%.*]], i8* nocapture [[B:%.*]]) #[[ATTR2]] { +; FULL-NEXT: entry: +; FULL-NEXT: [[L_I:%.*]] = alloca i8, i32 512, align 1 +; FULL-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META6:![0-9]+]]) +; FULL-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[A]], i8* [[TMP0]], i8** null, i64 0, metadata [[META6]]), !noalias !9 +; FULL-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i8.i64(i8** null, i64 0, metadata [[META11:![0-9]+]]) +; FULL-NEXT: [[TMP3:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i64(i8* [[C]], i8* [[TMP2]], i8** null, i64 0, metadata [[META11]]), !noalias !9 +; FULL-NEXT: call void @llvm.lifetime.start.p0i8(i64 512, i8* [[L_I]]) +; FULL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[B]], i64 16, i1 false) #[[ATTR2]], !noalias !9 +; FULL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[B]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR2]], !noalias !9 +; FULL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[TMP1]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR2]], !noalias !9 +; FULL-NEXT: call void @hey() #[[ATTR2]], !noalias !9 +; FULL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 16 [[L_I]], i8* align 16 [[TMP3]], i64 16, i1 false) #[[ATTR2]], !noalias !9 +; FULL-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[L_I]]) +; FULL-NEXT: ret void ; entry: tail call void @hello_cs(i8* noalias %a, i8* noalias %c, i8* %b) @@ -98,16 +162,25 @@ attributes #2 = { nounwind } attributes #3 = { nounwind uwtable } -; CHECK: !0 = !{!1} -; CHECK: !1 = distinct !{!1, !2, !"hello: %a"} -; CHECK: !2 = distinct !{!2, !"hello"} -; CHECK: !3 = !{!4} -; CHECK: !4 = distinct !{!4, !2, !"hello: %c"} -; CHECK: !5 = !{!1, !4} +; NONE-NOT: !0 = + +; SCOPES: !0 = !{!1} +; SCOPES-NEXT: !1 = distinct !{!1, !2, !"hello: %a"} +; SCOPES-NEXT: !2 = distinct !{!2, !"hello"} +; SCOPES-NEXT: !3 = !{!4} +; SCOPES-NEXT: !4 = distinct !{!4, !2, !"hello: %c"} +; SCOPES-NEXT: !5 = !{!1, !4} +; SCOPES-NEXT: !6 = !{!7} +; SCOPES-NEXT: !7 = distinct !{!7, !8, !"hello_cs: %a"} +; SCOPES-NEXT: !8 = distinct !{!8, !"hello_cs"} +; SCOPES-NEXT: !9 = !{!10} +; SCOPES-NEXT: !10 = distinct !{!10, !8, !"hello_cs: %c"} +; SCOPES-NEXT: !11 = !{!7, !10} + -; CHECK: !6 = !{!7} -; CHECK: !7 = distinct !{!7, !8, !"hello_cs: %a"} -; CHECK: !8 = distinct !{!8, !"hello_cs"} -; CHECK: !9 = !{!10} -; CHECK: !10 = distinct !{!10, !8, !"hello_cs: %c"} -; CHECK: !11 = !{!7, !10} +; FULL: !0 = !{!1} +; FULL-NEXT: !1 = distinct !{!1, !2, !"hello: %a"} +; FULL-NEXT: !2 = distinct !{!2, !"hello"} +; FULL-NEXT: !3 = !{!1, !4} +; FULL-NEXT: !4 = distinct !{!4, !2, !"hello: %c"} +; FULL-NEXT: !5 = !{!4} Index: llvm/test/Transforms/Inline/noalias-calls2.ll =================================================================== --- llvm/test/Transforms/Inline/noalias-calls2.ll +++ llvm/test/Transforms/Inline/noalias-calls2.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature -; RUN: opt -basic-aa -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s -; RUN: opt -aa-pipeline=basic-aa -passes=inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s +; RUN: opt -basic-aa -inline -enable-noalias-to-md-conversion --use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s +; RUN: opt -aa-pipeline=basic-aa -passes=inline -enable-noalias-to-md-conversion --use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" Index: llvm/test/Transforms/Inline/noalias-recursive.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/Inline/noalias-recursive.ll @@ -0,0 +1,199 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s --check-prefixes=SCOPES +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=full -S < %s | FileCheck %s --check-prefixes=FULL + +%class.ah = type { [8 x i8] } + +; Test for self recursion: + +; Function Attrs: nounwind uwtable +define void @Test01(%class.ah* noalias sret(%class.ah) align 8 %agg.result, i32 %n) local_unnamed_addr #0 !noalias !1 { +; SCOPES-LABEL: @Test01( +; SCOPES-NEXT: entry: +; SCOPES-NEXT: [[SWITCH:%.*]] = icmp eq i32 [[N:%.*]], 0 +; SCOPES-NEXT: br i1 [[SWITCH]], label [[SW_BB:%.*]], label [[SW_BB1:%.*]] +; SCOPES: sw.bb: +; SCOPES-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_AH:%.*]], %class.ah* [[AGG_RESULT:%.*]], i64 0, i32 0, i64 0 +; SCOPES-NEXT: store i8 42, i8* [[TMP0]], align 1, !noalias !1 +; SCOPES-NEXT: ret void +; SCOPES: sw.bb1: +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META4:![0-9]+]]) +; SCOPES-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_AH]], %class.ah* [[AGG_RESULT]], i64 0, i32 0, i64 0 +; SCOPES-NEXT: store i8 42, i8* [[TMP1]], align 1, !alias.scope !4, !noalias !7 +; SCOPES-NEXT: ret void +; +; FULL-LABEL: @Test01( +; FULL-NEXT: entry: +; FULL-NEXT: [[SWITCH:%.*]] = icmp eq i32 [[N:%.*]], 0 +; FULL-NEXT: br i1 [[SWITCH]], label [[SW_BB:%.*]], label [[SW_BB1:%.*]] +; FULL: sw.bb: +; FULL-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_AH:%.*]], %class.ah* [[AGG_RESULT:%.*]], i64 0, i32 0, i64 0 +; FULL-NEXT: store i8 42, i8* [[TMP0]], align 1, !noalias !1 +; FULL-NEXT: ret void +; FULL: sw.bb1: +; FULL-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_class.ahs.i64(%class.ah** null, i64 0, metadata [[META4:![0-9]+]]) +; FULL-NEXT: [[TMP2:%.*]] = call %class.ah* @llvm.noalias.p0s_class.ahs.p0i8.p0p0s_class.ahs.i64(%class.ah* [[AGG_RESULT]], i8* [[TMP1]], %class.ah** null, i64 0, metadata [[META4]]), !noalias !7 +; FULL-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[CLASS_AH]], %class.ah* [[TMP2]], i64 0, i32 0, i64 0 +; FULL-NEXT: store i8 42, i8* [[TMP3]], align 1, !noalias !8 +; FULL-NEXT: ret void +; +entry: + %switch = icmp eq i32 %n, 0 + br i1 %switch, label %sw.bb, label %sw.bb1 + +sw.bb: ; preds = %entry + %0 = getelementptr inbounds %class.ah, %class.ah* %agg.result, i64 0, i32 0, i64 0 + store i8 42, i8* %0, !noalias !1 + ret void + +sw.bb1: ; preds = %entry + call void @Test01(%class.ah* nonnull sret(%class.ah) align 8 %agg.result, i32 0), !noalias !1 + ret void +} + +; And equivalent version, but without the selfrecursion: + +; Function Attrs: nounwind uwtable +declare void @Test02c(%class.ah* noalias sret(%class.ah) align 8 %agg.result, i32 %n) local_unnamed_addr #0 + +; Function Attrs: nounwind uwtable +define void @Test02b(%class.ah* noalias sret(%class.ah) align 8 %agg.result, i32 %n) local_unnamed_addr #0 !noalias !4 { +; SCOPES-LABEL: @Test02b( +; SCOPES-NEXT: entry: +; SCOPES-NEXT: [[SWITCH:%.*]] = icmp eq i32 [[N:%.*]], 0 +; SCOPES-NEXT: br i1 [[SWITCH]], label [[SW_BB:%.*]], label [[SW_BB1:%.*]] +; SCOPES: sw.bb: +; SCOPES-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_AH:%.*]], %class.ah* [[AGG_RESULT:%.*]], i64 0, i32 0, i64 0 +; SCOPES-NEXT: store i8 42, i8* [[TMP0]], align 1, !noalias !10 +; SCOPES-NEXT: ret void +; SCOPES: sw.bb1: +; SCOPES-NEXT: call void @Test02c(%class.ah* nonnull sret([[CLASS_AH]]) align 8 [[AGG_RESULT]], i32 0), !noalias !10 +; SCOPES-NEXT: ret void +; +; FULL-LABEL: @Test02b( +; FULL-NEXT: entry: +; FULL-NEXT: [[SWITCH:%.*]] = icmp eq i32 [[N:%.*]], 0 +; FULL-NEXT: br i1 [[SWITCH]], label [[SW_BB:%.*]], label [[SW_BB1:%.*]] +; FULL: sw.bb: +; FULL-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_AH:%.*]], %class.ah* [[AGG_RESULT:%.*]], i64 0, i32 0, i64 0 +; FULL-NEXT: store i8 42, i8* [[TMP0]], align 1, !noalias !11 +; FULL-NEXT: ret void +; FULL: sw.bb1: +; FULL-NEXT: call void @Test02c(%class.ah* nonnull sret([[CLASS_AH]]) align 8 [[AGG_RESULT]], i32 0), !noalias !11 +; FULL-NEXT: ret void +; +entry: + %switch = icmp eq i32 %n, 0 + br i1 %switch, label %sw.bb, label %sw.bb1 + +sw.bb: ; preds = %entry + %0 = getelementptr inbounds %class.ah, %class.ah* %agg.result, i64 0, i32 0, i64 0 + store i8 42, i8* %0, !noalias !4 + ret void + +sw.bb1: ; preds = %entry + call void @Test02c(%class.ah* nonnull sret(%class.ah) align 8 %agg.result, i32 0), !noalias !4 + ret void +} + +; Function Attrs: nounwind uwtable +define void @Test02a(%class.ah* noalias sret(%class.ah) align 8 %agg.result, i32 %n) local_unnamed_addr #0 !noalias !7 { +; SCOPES-LABEL: @Test02a( +; SCOPES-NEXT: entry: +; SCOPES-NEXT: [[SWITCH:%.*]] = icmp eq i32 [[N:%.*]], 0 +; SCOPES-NEXT: br i1 [[SWITCH]], label [[SW_BB:%.*]], label [[SW_BB1:%.*]] +; SCOPES: sw.bb: +; SCOPES-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_AH:%.*]], %class.ah* [[AGG_RESULT:%.*]], i64 0, i32 0, i64 0 +; SCOPES-NEXT: store i8 42, i8* [[TMP0]], align 1, !noalias !13 +; SCOPES-NEXT: ret void +; SCOPES: sw.bb1: +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META16:![0-9]+]]) +; SCOPES-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[CLASS_AH]], %class.ah* [[AGG_RESULT]], i64 0, i32 0, i64 0 +; SCOPES-NEXT: store i8 42, i8* [[TMP1]], align 1, !alias.scope !16, !noalias !13 +; SCOPES-NEXT: ret void +; +; FULL-LABEL: @Test02a( +; FULL-NEXT: entry: +; FULL-NEXT: [[SWITCH:%.*]] = icmp eq i32 [[N:%.*]], 0 +; FULL-NEXT: br i1 [[SWITCH]], label [[SW_BB:%.*]], label [[SW_BB1:%.*]] +; FULL: sw.bb: +; FULL-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_AH:%.*]], %class.ah* [[AGG_RESULT:%.*]], i64 0, i32 0, i64 0 +; FULL-NEXT: store i8 42, i8* [[TMP0]], align 1, !noalias !14 +; FULL-NEXT: ret void +; FULL: sw.bb1: +; FULL-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0s_class.ahs.i64(%class.ah** null, i64 0, metadata [[META17:![0-9]+]]) +; FULL-NEXT: [[TMP2:%.*]] = call %class.ah* @llvm.noalias.p0s_class.ahs.p0i8.p0p0s_class.ahs.i64(%class.ah* [[AGG_RESULT]], i8* [[TMP1]], %class.ah** null, i64 0, metadata [[META17]]), !noalias !20 +; FULL-NEXT: [[TMP3:%.*]] = getelementptr inbounds [[CLASS_AH]], %class.ah* [[TMP2]], i64 0, i32 0, i64 0 +; FULL-NEXT: store i8 42, i8* [[TMP3]], align 1, !noalias !20 +; FULL-NEXT: ret void +; +entry: + %switch = icmp eq i32 %n, 0 + br i1 %switch, label %sw.bb, label %sw.bb1 + +sw.bb: ; preds = %entry + %0 = getelementptr inbounds %class.ah, %class.ah* %agg.result, i64 0, i32 0, i64 0 + store i8 42, i8* %0, !noalias !7 + ret void + +sw.bb1: ; preds = %entry + call void @Test02b(%class.ah* nonnull sret(%class.ah) align 8 %agg.result, i32 0), !noalias !7 + ret void +} + +attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.ident = !{!0} + +!0 = !{!"clang"} +!1 = !{!2} +!2 = distinct !{!2, !3, !"Test01: unknown function scope"} +!3 = distinct !{!3, !"Test01"} +!4 = !{!5} +!5 = distinct !{!5, !6, !"Test02b: unknown function scope"} +!6 = distinct !{!6, !"Test02b"} +!7 = !{!8} +!8 = distinct !{!8, !9, !"Test02a: unknown function scope"} +!9 = distinct !{!9, !"Test02a"} + +; SCOPES: !0 = !{!"clang"} +; SCOPES-NEXT: !1 = !{!2} +; SCOPES-NEXT: !2 = distinct !{!2, !3, !"Test01: unknown function scope"} +; SCOPES-NEXT: !3 = distinct !{!3, !"Test01"} +; SCOPES-NEXT: !4 = !{!5} +; SCOPES-NEXT: !5 = distinct !{!5, !6, !"Test01: %agg.result"} +; SCOPES-NEXT: !6 = distinct !{!6, !"Test01"} +; SCOPES-NEXT: !7 = !{!8, !2} +; SCOPES-NEXT: !8 = distinct !{!8, !9, !"Test01: unknown function scope"} +; SCOPES-NEXT: !9 = distinct !{!9, !"Test01"} +; SCOPES-NEXT: !10 = !{!11} +; SCOPES-NEXT: !11 = distinct !{!11, !12, !"Test02b: unknown function scope"} +; SCOPES-NEXT: !12 = distinct !{!12, !"Test02b"} +; SCOPES-NEXT: !13 = !{!14} +; SCOPES-NEXT: !14 = distinct !{!14, !15, !"Test02a: unknown function scope"} +; SCOPES-NEXT: !15 = distinct !{!15, !"Test02a"} +; SCOPES-NEXT: !16 = !{!17} +; SCOPES-NEXT: !17 = distinct !{!17, !18, !"Test02b: %agg.result"} +; SCOPES-NEXT: !18 = distinct !{!18, !"Test02b"} + +; FULL: !0 = !{!"clang"} +; FULL-NEXT: !1 = !{!2} +; FULL-NEXT: !2 = distinct !{!2, !3, !"Test01: unknown function scope"} +; FULL-NEXT: !3 = distinct !{!3, !"Test01"} +; FULL-NEXT: !4 = !{!5} +; FULL-NEXT: !5 = distinct !{!5, !6, !"Test01: %agg.result"} +; FULL-NEXT: !6 = distinct !{!6, !"Test01"} +; FULL-NEXT: !7 = !{!2, !5} +; FULL-NEXT: !8 = !{!9, !2, !5} +; FULL-NEXT: !9 = distinct !{!9, !10, !"Test01: unknown function scope"} +; FULL-NEXT: !10 = distinct !{!10, !"Test01"} +; FULL-NEXT: !11 = !{!12} +; FULL-NEXT: !12 = distinct !{!12, !13, !"Test02b: unknown function scope"} +; FULL-NEXT: !13 = distinct !{!13, !"Test02b"} +; FULL-NEXT: !14 = !{!15} +; FULL-NEXT: !15 = distinct !{!15, !16, !"Test02a: unknown function scope"} +; FULL-NEXT: !16 = distinct !{!16, !"Test02a"} +; FULL-NEXT: !17 = !{!18} +; FULL-NEXT: !18 = distinct !{!18, !19, !"Test02b: %agg.result"} +; FULL-NEXT: !19 = distinct !{!19, !"Test02b"} +; FULL-NEXT: !20 = !{!15, !18} Index: llvm/test/Transforms/Inline/noalias-scopes.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/Inline/noalias-scopes.ll @@ -0,0 +1,218 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=full -S < %s | FileCheck %s + +; verify that inlining result in scope duplication +; verify that llvm.noalias.decl is introduced at the location of the inlining + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nofree norecurse nounwind +define dso_local void @copy_npnp(i32* noalias nocapture %dst, i32* noalias nocapture readonly %src) local_unnamed_addr #0 { +; CHECK-LABEL: @copy_npnp( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[SRC:%.*]], ptr_provenance i32* undef, align 4, !tbaa [[TBAA2:![0-9]+]] +; CHECK-NEXT: store i32 [[TMP0]], i32* [[DST:%.*]], ptr_provenance i32* undef, align 4, !tbaa [[TBAA2]] +; CHECK-NEXT: ret void +; +entry: + %0 = load i32, i32* %src, ptr_provenance i32* undef, align 4, !tbaa !2 + store i32 %0, i32* %dst, ptr_provenance i32* undef, align 4, !tbaa !2 + ret void +} + +; Function Attrs: nounwind +define dso_local void @copy_rprp(i32* nocapture %dst, i32* nocapture readonly %src) local_unnamed_addr #1 { +; CHECK-LABEL: @copy_rprp( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META6:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META9:![0-9]+]]) +; CHECK-NEXT: [[TMP2:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[SRC:%.*]], i8* [[TMP1]], i32** null, i32** undef, i64 0, metadata [[META9]]), !tbaa [[TBAA11:![0-9]+]], !noalias !13 +; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[SRC]], ptr_provenance i32* [[TMP2]], align 4, !tbaa [[TBAA2]], !noalias !13 +; CHECK-NEXT: [[TMP4:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[DST:%.*]], i8* [[TMP0]], i32** null, i32** undef, i64 0, metadata [[META6]]), !tbaa [[TBAA11]], !noalias !13 +; CHECK-NEXT: store i32 [[TMP3]], i32* [[DST]], ptr_provenance i32* [[TMP4]], align 4, !tbaa [[TBAA2]], !noalias !13 +; CHECK-NEXT: ret void +; +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !6) + %1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !9) + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %src, i8* %1, i32** null, i32** undef, i64 0, metadata !9), !tbaa !11, !noalias !13 + %3 = load i32, i32* %src, ptr_provenance i32* %2, align 4, !tbaa !2, !noalias !13 + %4 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %dst, i8* %0, i32** null, i32** undef, i64 0, metadata !6), !tbaa !11, !noalias !13 + store i32 %3, i32* %dst, ptr_provenance i32* %4, align 4, !tbaa !2, !noalias !13 + ret void +} + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32**, i64, metadata) #2 + +; Function Attrs: nofree norecurse nounwind +define dso_local void @test_npnp(i32* nocapture %dst, i32* nocapture readonly %src, i32 %n) local_unnamed_addr #0 { +; CHECK-LABEL: @test_npnp( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META14:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[DST:%.*]], i8* [[TMP0]], i32** null, i64 0, metadata [[META14]]), !noalias !17 +; CHECK-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META19:![0-9]+]]) +; CHECK-NEXT: [[TMP3:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[SRC:%.*]], i8* [[TMP2]], i32** null, i64 0, metadata [[META19]]), !noalias !17 +; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[TMP3]], ptr_provenance i32* undef, align 4, !tbaa [[TBAA2]], !noalias !17 +; CHECK-NEXT: store i32 [[TMP4]], i32* [[TMP1]], ptr_provenance i32* undef, align 4, !tbaa [[TBAA2]], !noalias !17 +; CHECK-NEXT: br label [[DO_BODY:%.*]] +; CHECK: do.body: +; CHECK-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[DEC:%.*]], [[DO_BODY]] ] +; CHECK-NEXT: [[TMP5:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META20:![0-9]+]]) +; CHECK-NEXT: [[TMP6:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[DST]], i8* [[TMP5]], i32** null, i64 0, metadata [[META20]]), !noalias !23 +; CHECK-NEXT: [[TMP7:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META25:![0-9]+]]) +; CHECK-NEXT: [[TMP8:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[SRC]], i8* [[TMP7]], i32** null, i64 0, metadata [[META25]]), !noalias !23 +; CHECK-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP8]], ptr_provenance i32* undef, align 4, !tbaa [[TBAA2]], !noalias !23 +; CHECK-NEXT: store i32 [[TMP9]], i32* [[TMP6]], ptr_provenance i32* undef, align 4, !tbaa [[TBAA2]], !noalias !23 +; CHECK-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META26:![0-9]+]]) +; CHECK-NEXT: [[TMP11:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[DST]], i8* [[TMP10]], i32** null, i64 0, metadata [[META26]]), !noalias !29 +; CHECK-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META31:![0-9]+]]) +; CHECK-NEXT: [[TMP13:%.*]] = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* [[SRC]], i8* [[TMP12]], i32** null, i64 0, metadata [[META31]]), !noalias !29 +; CHECK-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], ptr_provenance i32* undef, align 4, !tbaa [[TBAA2]], !noalias !29 +; CHECK-NEXT: store i32 [[TMP14]], i32* [[TMP11]], ptr_provenance i32* undef, align 4, !tbaa [[TBAA2]], !noalias !29 +; CHECK-NEXT: [[DEC]] = add nsw i32 [[N_ADDR_0]], -1 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 +; CHECK-NEXT: br i1 [[TOBOOL]], label [[DO_END:%.*]], label [[DO_BODY]] +; CHECK: do.end: +; CHECK-NEXT: ret void +; +entry: + tail call void @copy_npnp(i32* %dst, i32* %src) + br label %do.body + +do.body: ; preds = %do.body, %entry + %n.addr.0 = phi i32 [ %n, %entry ], [ %dec, %do.body ] + tail call void @copy_npnp(i32* %dst, i32* %src) + tail call void @copy_npnp(i32* %dst, i32* %src) + %dec = add nsw i32 %n.addr.0, -1 + %tobool = icmp eq i32 %n.addr.0, 0 + br i1 %tobool, label %do.end, label %do.body + +do.end: ; preds = %do.body + ret void +} + +; Function Attrs: nounwind +define dso_local void @test_rprp(i32* nocapture %dst, i32* nocapture readonly %src, i32 %n) local_unnamed_addr #1 { +; CHECK-LABEL: @test_rprp( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META32:![0-9]+]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META35:![0-9]+]]) #[[ATTR5]] +; CHECK-NEXT: [[TMP2:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[SRC:%.*]], i8* [[TMP1]], i32** null, i32** undef, i64 0, metadata [[META35]]) #[[ATTR5]], !tbaa [[TBAA11]], !noalias !37 +; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[SRC]], ptr_provenance i32* [[TMP2]], align 4, !tbaa [[TBAA2]], !noalias !37 +; CHECK-NEXT: [[TMP4:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[DST:%.*]], i8* [[TMP0]], i32** null, i32** undef, i64 0, metadata [[META32]]) #[[ATTR5]], !tbaa [[TBAA11]], !noalias !37 +; CHECK-NEXT: store i32 [[TMP3]], i32* [[DST]], ptr_provenance i32* [[TMP4]], align 4, !tbaa [[TBAA2]], !noalias !37 +; CHECK-NEXT: br label [[DO_BODY:%.*]] +; CHECK: do.body: +; CHECK-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[DEC:%.*]], [[DO_BODY]] ] +; CHECK-NEXT: [[TMP5:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META38:![0-9]+]]) #[[ATTR5]] +; CHECK-NEXT: [[TMP6:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META41:![0-9]+]]) #[[ATTR5]] +; CHECK-NEXT: [[TMP7:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[SRC]], i8* [[TMP6]], i32** null, i32** undef, i64 0, metadata [[META41]]) #[[ATTR5]], !tbaa [[TBAA11]], !noalias !43 +; CHECK-NEXT: [[TMP8:%.*]] = load i32, i32* [[SRC]], ptr_provenance i32* [[TMP7]], align 4, !tbaa [[TBAA2]], !noalias !43 +; CHECK-NEXT: [[TMP9:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[DST]], i8* [[TMP5]], i32** null, i32** undef, i64 0, metadata [[META38]]) #[[ATTR5]], !tbaa [[TBAA11]], !noalias !43 +; CHECK-NEXT: store i32 [[TMP8]], i32* [[DST]], ptr_provenance i32* [[TMP9]], align 4, !tbaa [[TBAA2]], !noalias !43 +; CHECK-NEXT: [[TMP10:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META44:![0-9]+]]) #[[ATTR5]] +; CHECK-NEXT: [[TMP11:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META47:![0-9]+]]) #[[ATTR5]] +; CHECK-NEXT: [[TMP12:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[SRC]], i8* [[TMP11]], i32** null, i32** undef, i64 0, metadata [[META47]]) #[[ATTR5]], !tbaa [[TBAA11]], !noalias !49 +; CHECK-NEXT: [[TMP13:%.*]] = load i32, i32* [[SRC]], ptr_provenance i32* [[TMP12]], align 4, !tbaa [[TBAA2]], !noalias !49 +; CHECK-NEXT: [[TMP14:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[DST]], i8* [[TMP10]], i32** null, i32** undef, i64 0, metadata [[META44]]) #[[ATTR5]], !tbaa [[TBAA11]], !noalias !49 +; CHECK-NEXT: store i32 [[TMP13]], i32* [[DST]], ptr_provenance i32* [[TMP14]], align 4, !tbaa [[TBAA2]], !noalias !49 +; CHECK-NEXT: [[DEC]] = add nsw i32 [[N_ADDR_0]], -1 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0 +; CHECK-NEXT: br i1 [[TOBOOL]], label [[DO_END:%.*]], label [[DO_BODY]] +; CHECK: do.end: +; CHECK-NEXT: ret void +; +entry: + tail call void @copy_rprp(i32* %dst, i32* %src) + br label %do.body + +do.body: ; preds = %do.body, %entry + %n.addr.0 = phi i32 [ %n, %entry ], [ %dec, %do.body ] + tail call void @copy_rprp(i32* %dst, i32* %src) + tail call void @copy_rprp(i32* %dst, i32* %src) + %dec = add nsw i32 %n.addr.0, -1 + %tobool = icmp eq i32 %n.addr.0, 0 + br i1 %tobool, label %do.end, label %do.body + +do.end: ; preds = %do.body + ret void +} + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32*, i8*, i32**, i32**, i64, metadata) #3 + +attributes #0 = { nofree norecurse nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { argmemonly nounwind } +attributes #3 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3, !3, i64 0, i64 4} +!3 = !{!4, i64 4, !"int"} +!4 = !{!5, i64 1, !"omnipotent char"} +!5 = !{!"Simple C/C++ TBAA"} +!6 = !{!7} +!7 = distinct !{!7, !8, !"copy_rprp: rdst"} +!8 = distinct !{!8, !"copy_rprp"} +!9 = !{!10} +!10 = distinct !{!10, !8, !"copy_rprp: rsrc"} +!11 = !{!12, !12, i64 0, i64 4} +!12 = !{!4, i64 4, !"any pointer"} +!13 = !{!7, !10} + +; CHECK: !0 = !{i32 1, !"wchar_size", i32 4} +; CHECK-NEXT: !1 = !{!"clang"} +; CHECK-NEXT: !2 = !{!3, !3, i64 0, i64 4} +; CHECK-NEXT: !3 = !{!4, i64 4, !"int"} +; CHECK-NEXT: !4 = !{!5, i64 1, !"omnipotent char"} +; CHECK-NEXT: !5 = !{!"Simple C/C++ TBAA"} +; CHECK-NEXT: !6 = !{!7} +; CHECK-NEXT: !7 = distinct !{!7, !8, !"copy_rprp: rdst"} +; CHECK-NEXT: !8 = distinct !{!8, !"copy_rprp"} +; CHECK-NEXT: !9 = !{!10} +; CHECK-NEXT: !10 = distinct !{!10, !8, !"copy_rprp: rsrc"} +; CHECK-NEXT: !11 = !{!12, !12, i64 0, i64 4} +; CHECK-NEXT: !12 = !{!4, i64 4, !"any pointer"} +; CHECK-NEXT: !13 = !{!7, !10} +; CHECK-NEXT: !14 = !{!15} +; CHECK-NEXT: !15 = distinct !{!15, !16, !"copy_npnp: %dst"} +; CHECK-NEXT: !16 = distinct !{!16, !"copy_npnp"} +; CHECK-NEXT: !17 = !{!15, !18} +; CHECK-NEXT: !18 = distinct !{!18, !16, !"copy_npnp: %src"} +; CHECK-NEXT: !19 = !{!18} +; CHECK-NEXT: !20 = !{!21} +; CHECK-NEXT: !21 = distinct !{!21, !22, !"copy_npnp: %dst"} +; CHECK-NEXT: !22 = distinct !{!22, !"copy_npnp"} +; CHECK-NEXT: !23 = !{!21, !24} +; CHECK-NEXT: !24 = distinct !{!24, !22, !"copy_npnp: %src"} +; CHECK-NEXT: !25 = !{!24} +; CHECK-NEXT: !26 = !{!27} +; CHECK-NEXT: !27 = distinct !{!27, !28, !"copy_npnp: %dst"} +; CHECK-NEXT: !28 = distinct !{!28, !"copy_npnp"} +; CHECK-NEXT: !29 = !{!27, !30} +; CHECK-NEXT: !30 = distinct !{!30, !28, !"copy_npnp: %src"} +; CHECK-NEXT: !31 = !{!30} +; CHECK-NEXT: !32 = !{!33} +; CHECK-NEXT: !33 = distinct !{!33, !34, !"copy_rprp: rdst"} +; CHECK-NEXT: !34 = distinct !{!34, !"copy_rprp"} +; CHECK-NEXT: !35 = !{!36} +; CHECK-NEXT: !36 = distinct !{!36, !34, !"copy_rprp: rsrc"} +; CHECK-NEXT: !37 = !{!33, !36} +; CHECK-NEXT: !38 = !{!39} +; CHECK-NEXT: !39 = distinct !{!39, !40, !"copy_rprp: rdst"} +; CHECK-NEXT: !40 = distinct !{!40, !"copy_rprp"} +; CHECK-NEXT: !41 = !{!42} +; CHECK-NEXT: !42 = distinct !{!42, !40, !"copy_rprp: rsrc"} +; CHECK-NEXT: !43 = !{!39, !42} +; CHECK-NEXT: !44 = !{!45} +; CHECK-NEXT: !45 = distinct !{!45, !46, !"copy_rprp: rdst"} +; CHECK-NEXT: !46 = distinct !{!46, !"copy_rprp"} +; CHECK-NEXT: !47 = !{!48} +; CHECK-NEXT: !48 = distinct !{!48, !46, !"copy_rprp: rsrc"} +; CHECK-NEXT: !49 = !{!45, !48} Index: llvm/test/Transforms/Inline/noalias.ll =================================================================== --- llvm/test/Transforms/Inline/noalias.ll +++ llvm/test/Transforms/Inline/noalias.ll @@ -1,8 +1,18 @@ -; RUN: opt -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=none -S < %s | FileCheck %s -check-prefixes=CHECK,NONE +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s -check-prefixes=CHECK,SCOPES +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=full -S < %s | FileCheck %s -check-prefixes=CHECK,FULL target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" define void @hello(float* noalias nocapture %a, float* nocapture readonly %c) #0 { +; CHECK-LABEL: @hello( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C:%.*]], align 4 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5 +; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX]], align 4 +; CHECK-NEXT: ret void +; entry: %0 = load float, float* %c, align 4 %arrayidx = getelementptr inbounds float, float* %a, i64 5 @@ -11,6 +21,39 @@ } define void @foo(float* nocapture %a, float* nocapture readonly %c) #0 { +; NONE-LABEL: @foo( +; NONE-NEXT: entry: +; NONE-NEXT: [[TMP0:%.*]] = load float, float* [[C:%.*]], align 4 +; NONE-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5 +; NONE-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4 +; NONE-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4 +; NONE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; NONE-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4 +; NONE-NEXT: ret void +; +; SCOPES-LABEL: @foo( +; SCOPES-NEXT: entry: +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]]) +; SCOPES-NEXT: [[TMP0:%.*]] = load float, float* [[C:%.*]], align 4, !noalias !0 +; SCOPES-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5 +; SCOPES-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !0 +; SCOPES-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4 +; SCOPES-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; SCOPES-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4 +; SCOPES-NEXT: ret void +; +; FULL-LABEL: @foo( +; FULL-NEXT: entry: +; FULL-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META0:![0-9]+]]) +; FULL-NEXT: [[TMP1:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[A:%.*]], i8* [[TMP0]], float** null, i64 0, metadata [[META0]]), !noalias !0 +; FULL-NEXT: [[TMP2:%.*]] = load float, float* [[C:%.*]], align 4, !noalias !0 +; FULL-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[TMP1]], i64 5 +; FULL-NEXT: store float [[TMP2]], float* [[ARRAYIDX_I]], align 4, !noalias !0 +; FULL-NEXT: [[TMP3:%.*]] = load float, float* [[C]], align 4 +; FULL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; FULL-NEXT: store float [[TMP3]], float* [[ARRAYIDX]], align 4 +; FULL-NEXT: ret void +; entry: tail call void @hello(float* %a, float* %c) %0 = load float, float* %c, align 4 @@ -19,19 +62,16 @@ ret void } -; CHECK-LABEL: define void @foo(float* nocapture %a, float* nocapture readonly %c) #0 { -; CHECK: entry: -; CHECK: call void @llvm.experimental.noalias.scope.decl -; CHECK: [[TMP0:%.+]] = load float, float* %c, align 4, !noalias !0 -; CHECK: %arrayidx.i = getelementptr inbounds float, float* %a, i64 5 -; CHECK: store float [[TMP0]], float* %arrayidx.i, align 4, !alias.scope !0 -; CHECK: [[TMP1:%.+]] = load float, float* %c, align 4 -; CHECK: %arrayidx = getelementptr inbounds float, float* %a, i64 7 -; CHECK: store float [[TMP1]], float* %arrayidx, align 4 -; CHECK: ret void -; CHECK: } - define void @hello2(float* noalias nocapture %a, float* noalias nocapture %b, float* nocapture readonly %c) #0 { +; CHECK-LABEL: @hello2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C:%.*]], align 4 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5 +; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 8 +; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX1]], align 4 +; CHECK-NEXT: ret void +; entry: %0 = load float, float* %c, align 4 %arrayidx = getelementptr inbounds float, float* %a, i64 5 @@ -42,6 +82,48 @@ } define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 { +; NONE-LABEL: @foo2( +; NONE-NEXT: entry: +; NONE-NEXT: [[TMP0:%.*]] = load float, float* [[C:%.*]], align 4 +; NONE-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5 +; NONE-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4 +; NONE-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 8 +; NONE-NEXT: store float [[TMP0]], float* [[ARRAYIDX1_I]], align 4 +; NONE-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4 +; NONE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; NONE-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4 +; NONE-NEXT: ret void +; +; SCOPES-LABEL: @foo2( +; SCOPES-NEXT: entry: +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META6:![0-9]+]]) +; SCOPES-NEXT: [[TMP0:%.*]] = load float, float* [[C:%.*]], align 4, !noalias !8 +; SCOPES-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5 +; SCOPES-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !3, !noalias !6 +; SCOPES-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 8 +; SCOPES-NEXT: store float [[TMP0]], float* [[ARRAYIDX1_I]], align 4, !alias.scope !6, !noalias !3 +; SCOPES-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4 +; SCOPES-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; SCOPES-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4 +; SCOPES-NEXT: ret void +; +; FULL-LABEL: @foo2( +; FULL-NEXT: entry: +; FULL-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META3:![0-9]+]]) +; FULL-NEXT: [[TMP1:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[A:%.*]], i8* [[TMP0]], float** null, i64 0, metadata [[META3]]), !noalias !6 +; FULL-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META8:![0-9]+]]) +; FULL-NEXT: [[TMP3:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[B:%.*]], i8* [[TMP2]], float** null, i64 0, metadata [[META8]]), !noalias !6 +; FULL-NEXT: [[TMP4:%.*]] = load float, float* [[C:%.*]], align 4, !noalias !6 +; FULL-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[TMP1]], i64 5 +; FULL-NEXT: store float [[TMP4]], float* [[ARRAYIDX_I]], align 4, !noalias !6 +; FULL-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[TMP3]], i64 8 +; FULL-NEXT: store float [[TMP4]], float* [[ARRAYIDX1_I]], align 4, !noalias !6 +; FULL-NEXT: [[TMP5:%.*]] = load float, float* [[C]], align 4 +; FULL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; FULL-NEXT: store float [[TMP5]], float* [[ARRAYIDX]], align 4 +; FULL-NEXT: ret void +; entry: tail call void @hello2(float* %a, float* %b, float* %c) %0 = load float, float* %c, align 4 @@ -50,29 +132,27 @@ ret void } -; CHECK-LABEL: define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 { -; CHECK: entry: -; CHECK: call void @llvm.experimental.noalias.scope.decl(metadata !3) -; CHECK: call void @llvm.experimental.noalias.scope.decl(metadata !6) -; CHECK: [[TMP0:%.+]] = load float, float* %c, align 4, !noalias !8 -; CHECK: %arrayidx.i = getelementptr inbounds float, float* %a, i64 5 -; CHECK: store float [[TMP0]], float* %arrayidx.i, align 4, !alias.scope !3, !noalias !6 -; CHECK: %arrayidx1.i = getelementptr inbounds float, float* %b, i64 8 -; CHECK: store float [[TMP0]], float* %arrayidx1.i, align 4, !alias.scope !6, !noalias !3 -; CHECK: [[TMP1:%.+]] = load float, float* %c, align 4 -; CHECK: %arrayidx = getelementptr inbounds float, float* %a, i64 7 -; CHECK: store float [[TMP1]], float* %arrayidx, align 4 -; CHECK: ret void -; CHECK: } - attributes #0 = { nounwind uwtable } +attributes #1 = { argmemonly nounwind } + +; NONE-NOT: !0 = + +; SCOPES: !0 = !{!1} +; SCOPES-NEXT: !1 = distinct !{!1, !2, !"hello: %a"} +; SCOPES-NEXT: !2 = distinct !{!2, !"hello"} +; SCOPES-NEXT: !3 = !{!4} +; SCOPES-NEXT: !4 = distinct !{!4, !5, !"hello2: %a"} +; SCOPES-NEXT: !5 = distinct !{!5, !"hello2"} +; SCOPES-NEXT: !6 = !{!7} +; SCOPES-NEXT: !7 = distinct !{!7, !5, !"hello2: %b"} +; SCOPES-NEXT: !8 = !{!4, !7} -; CHECK: !0 = !{!1} -; CHECK: !1 = distinct !{!1, !2, !"hello: %a"} -; CHECK: !2 = distinct !{!2, !"hello"} -; CHECK: !3 = !{!4} -; CHECK: !4 = distinct !{!4, !5, !"hello2: %a"} -; CHECK: !5 = distinct !{!5, !"hello2"} -; CHECK: !6 = !{!7} -; CHECK: !7 = distinct !{!7, !5, !"hello2: %b"} -; CHECK: !8 = !{!4, !7} +; FULL: !0 = !{!1} +; FULL-NEXT: !1 = distinct !{!1, !2, !"hello: %a"} +; FULL-NEXT: !2 = distinct !{!2, !"hello"} +; FULL-NEXT: !3 = !{!4} +; FULL-NEXT: !4 = distinct !{!4, !5, !"hello2: %a"} +; FULL-NEXT: !5 = distinct !{!5, !"hello2"} +; FULL-NEXT: !6 = !{!4, !7} +; FULL-NEXT: !7 = distinct !{!7, !5, !"hello2: %b"} +; FULL-NEXT: !8 = !{!7} Index: llvm/test/Transforms/Inline/noalias2.ll =================================================================== --- llvm/test/Transforms/Inline/noalias2.ll +++ llvm/test/Transforms/Inline/noalias2.ll @@ -1,13 +1,17 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature -; RUN: opt -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s -; RUN: opt -inline -enable-noalias-to-md-conversion --enable-knowledge-retention -S < %s | FileCheck %s +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=none -S < %s | FileCheck %s --check-prefixes=CHECK,NONE +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=none --enable-knowledge-retention -S < %s | FileCheck %s --check-prefixes=CHECK,NONE +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s -check-prefixes=CHECK,SCOPES +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=scopes --enable-knowledge-retention -S < %s | FileCheck %s --check-prefixes=CHECK,SCOPES +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=full -S < %s | FileCheck %s -check-prefixes=CHECK,FULL +; RUN: opt -inline -enable-noalias-to-md-conversion -use-noalias-intrinsic-during-inlining=full --enable-knowledge-retention -S < %s | FileCheck %s --check-prefixes=CHECK,FULL target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" define void @hello(float* noalias nocapture %a, float* noalias nocapture readonly %c) #0 { ; CHECK-LABEL: define {{[^@]+}}@hello -; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) [[ATTR0:#.*]] { +; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 5 @@ -22,18 +26,44 @@ } define void @foo(float* noalias nocapture %a, float* noalias nocapture readonly %c) #0 { -; CHECK-LABEL: define {{[^@]+}}@foo -; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) [[ATTR0]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !0) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !3) -; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !3, !noalias !0 -; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5 -; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !0, !noalias !3 -; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4 -; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 -; CHECK-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4 -; CHECK-NEXT: ret void +; NONE-LABEL: define {{[^@]+}}@foo +; NONE-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) #[[ATTR0]] { +; NONE-NEXT: entry: +; NONE-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4 +; NONE-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5 +; NONE-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4 +; NONE-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4 +; NONE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; NONE-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4 +; NONE-NEXT: ret void +; +; SCOPES-LABEL: define {{[^@]+}}@foo +; SCOPES-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) #[[ATTR0]] { +; SCOPES-NEXT: entry: +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]]) +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) +; SCOPES-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !3, !noalias !0 +; SCOPES-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5 +; SCOPES-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !0, !noalias !3 +; SCOPES-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4 +; SCOPES-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; SCOPES-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4 +; SCOPES-NEXT: ret void +; +; FULL-LABEL: define {{[^@]+}}@foo +; FULL-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) #[[ATTR0]] { +; FULL-NEXT: entry: +; FULL-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META0:![0-9]+]]) +; FULL-NEXT: [[TMP1:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[A]], i8* [[TMP0]], float** null, i64 0, metadata [[META0]]), !noalias !3 +; FULL-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META5:![0-9]+]]) +; FULL-NEXT: [[TMP3:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[C]], i8* [[TMP2]], float** null, i64 0, metadata [[META5]]), !noalias !3 +; FULL-NEXT: [[TMP4:%.*]] = load float, float* [[TMP3]], align 4, !noalias !3 +; FULL-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[TMP1]], i64 5 +; FULL-NEXT: store float [[TMP4]], float* [[ARRAYIDX_I]], align 4, !noalias !3 +; FULL-NEXT: [[TMP5:%.*]] = load float, float* [[C]], align 4 +; FULL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; FULL-NEXT: store float [[TMP5]], float* [[ARRAYIDX]], align 4 +; FULL-NEXT: ret void ; entry: tail call void @hello(float* %a, float* %c) @@ -45,7 +75,7 @@ define void @hello2(float* noalias nocapture %a, float* noalias nocapture %b, float* nocapture readonly %c) #0 { ; CHECK-LABEL: define {{[^@]+}}@hello2 -; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) [[ATTR0]] { +; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) #[[ATTR0]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 6 @@ -66,30 +96,80 @@ ; Check that when hello() is inlined into foo(), and then foo() is inlined into ; foo2(), the noalias scopes are properly concatenated. define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 { -; CHECK-LABEL: define {{[^@]+}}@foo2 -; CHECK-SAME: (float* nocapture [[A:%.*]], float* nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) [[ATTR0]] { -; CHECK-NEXT: entry: -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !5) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !8) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !10) [[ATTR2:#.*]] -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !13) [[ATTR2]] -; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !15, !noalias !16 -; CHECK-NEXT: [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5 -; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4, !alias.scope !16, !noalias !15 -; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4, !alias.scope !8, !noalias !5 -; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 -; CHECK-NEXT: store float [[TMP1]], float* [[ARRAYIDX_I]], align 4, !alias.scope !5, !noalias !8 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !17) -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !20) -; CHECK-NEXT: [[TMP2:%.*]] = load float, float* [[C]], align 4, !noalias !22 -; CHECK-NEXT: [[ARRAYIDX_I1:%.*]] = getelementptr inbounds float, float* [[A]], i64 6 -; CHECK-NEXT: store float [[TMP2]], float* [[ARRAYIDX_I1]], align 4, !alias.scope !17, !noalias !20 -; CHECK-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B]], i64 8 -; CHECK-NEXT: store float [[TMP2]], float* [[ARRAYIDX1_I]], align 4, !alias.scope !20, !noalias !17 -; CHECK-NEXT: [[TMP3:%.*]] = load float, float* [[C]], align 4 -; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 -; CHECK-NEXT: store float [[TMP3]], float* [[ARRAYIDX]], align 4 -; CHECK-NEXT: ret void +; NONE-LABEL: define {{[^@]+}}@foo2 +; NONE-SAME: (float* nocapture [[A:%.*]], float* nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) #[[ATTR0]] { +; NONE-NEXT: entry: +; NONE-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4 +; NONE-NEXT: [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5 +; NONE-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4 +; NONE-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4 +; NONE-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; NONE-NEXT: store float [[TMP1]], float* [[ARRAYIDX_I]], align 4 +; NONE-NEXT: [[TMP2:%.*]] = load float, float* [[C]], align 4 +; NONE-NEXT: [[ARRAYIDX_I1:%.*]] = getelementptr inbounds float, float* [[A]], i64 6 +; NONE-NEXT: store float [[TMP2]], float* [[ARRAYIDX_I1]], align 4 +; NONE-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B]], i64 8 +; NONE-NEXT: store float [[TMP2]], float* [[ARRAYIDX1_I]], align 4 +; NONE-NEXT: [[TMP3:%.*]] = load float, float* [[C]], align 4 +; NONE-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; NONE-NEXT: store float [[TMP3]], float* [[ARRAYIDX]], align 4 +; NONE-NEXT: ret void +; +; SCOPES-LABEL: define {{[^@]+}}@foo2 +; SCOPES-SAME: (float* nocapture [[A:%.*]], float* nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) #[[ATTR0]] { +; SCOPES-NEXT: entry: +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META8:![0-9]+]]) +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META10:![0-9]+]]) #[[ATTR2:[0-9]+]] +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) #[[ATTR2]] +; SCOPES-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !15, !noalias !16 +; SCOPES-NEXT: [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5 +; SCOPES-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4, !alias.scope !16, !noalias !15 +; SCOPES-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4, !alias.scope !8, !noalias !5 +; SCOPES-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; SCOPES-NEXT: store float [[TMP1]], float* [[ARRAYIDX_I]], align 4, !alias.scope !5, !noalias !8 +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META17:![0-9]+]]) +; SCOPES-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META20:![0-9]+]]) +; SCOPES-NEXT: [[TMP2:%.*]] = load float, float* [[C]], align 4, !noalias !22 +; SCOPES-NEXT: [[ARRAYIDX_I1:%.*]] = getelementptr inbounds float, float* [[A]], i64 6 +; SCOPES-NEXT: store float [[TMP2]], float* [[ARRAYIDX_I1]], align 4, !alias.scope !17, !noalias !20 +; SCOPES-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B]], i64 8 +; SCOPES-NEXT: store float [[TMP2]], float* [[ARRAYIDX1_I]], align 4, !alias.scope !20, !noalias !17 +; SCOPES-NEXT: [[TMP3:%.*]] = load float, float* [[C]], align 4 +; SCOPES-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; SCOPES-NEXT: store float [[TMP3]], float* [[ARRAYIDX]], align 4 +; SCOPES-NEXT: ret void +; +; FULL-LABEL: define {{[^@]+}}@foo2 +; FULL-SAME: (float* nocapture [[A:%.*]], float* nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) #[[ATTR0]] { +; FULL-NEXT: entry: +; FULL-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META6:![0-9]+]]) +; FULL-NEXT: [[TMP1:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[A]], i8* [[TMP0]], float** null, i64 0, metadata [[META6]]), !noalias !9 +; FULL-NEXT: [[TMP2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META11:![0-9]+]]) +; FULL-NEXT: [[TMP3:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[C]], i8* [[TMP2]], float** null, i64 0, metadata [[META11]]), !noalias !9 +; FULL-NEXT: [[TMP4:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META12:![0-9]+]]) #[[ATTR3:[0-9]+]], !noalias !9 +; FULL-NEXT: [[TMP5:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[TMP1]], i8* [[TMP4]], float** null, i64 0, metadata [[META12]]) #[[ATTR3]], !noalias !15 +; FULL-NEXT: [[TMP6:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META17:![0-9]+]]) #[[ATTR3]], !noalias !9 +; FULL-NEXT: [[TMP7:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[TMP3]], i8* [[TMP6]], float** null, i64 0, metadata [[META17]]) #[[ATTR3]], !noalias !15 +; FULL-NEXT: [[TMP8:%.*]] = load float, float* [[TMP7]], align 4, !noalias !15 +; FULL-NEXT: [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, float* [[TMP5]], i64 5 +; FULL-NEXT: store float [[TMP8]], float* [[ARRAYIDX_I_I]], align 4, !noalias !15 +; FULL-NEXT: [[TMP9:%.*]] = load float, float* [[TMP3]], align 4, !noalias !9 +; FULL-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[TMP1]], i64 7 +; FULL-NEXT: store float [[TMP9]], float* [[ARRAYIDX_I]], align 4, !noalias !9 +; FULL-NEXT: [[TMP10:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META18:![0-9]+]]) +; FULL-NEXT: [[TMP11:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[A]], i8* [[TMP10]], float** null, i64 0, metadata [[META18]]), !noalias !21 +; FULL-NEXT: [[TMP12:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0f32.i64(float** null, i64 0, metadata [[META23:![0-9]+]]) +; FULL-NEXT: [[TMP13:%.*]] = call float* @llvm.noalias.p0f32.p0i8.p0p0f32.i64(float* [[B]], i8* [[TMP12]], float** null, i64 0, metadata [[META23]]), !noalias !21 +; FULL-NEXT: [[TMP14:%.*]] = load float, float* [[C]], align 4, !noalias !21 +; FULL-NEXT: [[ARRAYIDX_I1:%.*]] = getelementptr inbounds float, float* [[TMP11]], i64 6 +; FULL-NEXT: store float [[TMP14]], float* [[ARRAYIDX_I1]], align 4, !noalias !21 +; FULL-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[TMP13]], i64 8 +; FULL-NEXT: store float [[TMP14]], float* [[ARRAYIDX1_I]], align 4, !noalias !21 +; FULL-NEXT: [[TMP15:%.*]] = load float, float* [[C]], align 4 +; FULL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7 +; FULL-NEXT: store float [[TMP15]], float* [[ARRAYIDX]], align 4 +; FULL-NEXT: ret void ; entry: tail call void @foo(float* %a, float* %c) @@ -100,29 +180,55 @@ ret void } -; CHECK: !0 = !{!1} -; CHECK: !1 = distinct !{!1, !2, !"hello: %a"} -; CHECK: !2 = distinct !{!2, !"hello"} -; CHECK: !3 = !{!4} -; CHECK: !4 = distinct !{!4, !2, !"hello: %c"} -; CHECK: !5 = !{!6} -; CHECK: !6 = distinct !{!6, !7, !"foo: %a"} -; CHECK: !7 = distinct !{!7, !"foo"} -; CHECK: !8 = !{!9} -; CHECK: !9 = distinct !{!9, !7, !"foo: %c"} -; CHECK: !10 = !{!11} -; CHECK: !11 = distinct !{!11, !12, !"hello: %a"} -; CHECK: !12 = distinct !{!12, !"hello"} -; CHECK: !13 = !{!14} -; CHECK: !14 = distinct !{!14, !12, !"hello: %c"} -; CHECK: !15 = !{!14, !9} -; CHECK: !16 = !{!11, !6} -; CHECK: !17 = !{!18} -; CHECK: !18 = distinct !{!18, !19, !"hello2: %a"} -; CHECK: !19 = distinct !{!19, !"hello2"} -; CHECK: !20 = !{!21} -; CHECK: !21 = distinct !{!21, !19, !"hello2: %b"} -; CHECK: !22 = !{!18, !21} - attributes #0 = { nounwind uwtable } +; NONE-NOT: !0 = + +; SCOPES: !0 = !{!1} +; SCOPES-NEXT: !1 = distinct !{!1, !2, !"hello: %a"} +; SCOPES-NEXT: !2 = distinct !{!2, !"hello"} +; SCOPES-NEXT: !3 = !{!4} +; SCOPES-NEXT: !4 = distinct !{!4, !2, !"hello: %c"} +; SCOPES-NEXT: !5 = !{!6} +; SCOPES-NEXT: !6 = distinct !{!6, !7, !"foo: %a"} +; SCOPES-NEXT: !7 = distinct !{!7, !"foo"} +; SCOPES-NEXT: !8 = !{!9} +; SCOPES-NEXT: !9 = distinct !{!9, !7, !"foo: %c"} +; SCOPES-NEXT: !10 = !{!11} +; SCOPES-NEXT: !11 = distinct !{!11, !12, !"hello: %a"} +; SCOPES-NEXT: !12 = distinct !{!12, !"hello"} +; SCOPES-NEXT: !13 = !{!14} +; SCOPES-NEXT: !14 = distinct !{!14, !12, !"hello: %c"} +; SCOPES-NEXT: !15 = !{!14, !9} +; SCOPES-NEXT: !16 = !{!11, !6} +; SCOPES-NEXT: !17 = !{!18} +; SCOPES-NEXT: !18 = distinct !{!18, !19, !"hello2: %a"} +; SCOPES-NEXT: !19 = distinct !{!19, !"hello2"} +; SCOPES-NEXT: !20 = !{!21} +; SCOPES-NEXT: !21 = distinct !{!21, !19, !"hello2: %b"} +; SCOPES-NEXT: !22 = !{!18, !21} + +; FULL: !0 = !{!1} +; FULL-NEXT: !1 = distinct !{!1, !2, !"hello: %a"} +; FULL-NEXT: !2 = distinct !{!2, !"hello"} +; FULL-NEXT: !3 = !{!1, !4} +; FULL-NEXT: !4 = distinct !{!4, !2, !"hello: %c"} +; FULL-NEXT: !5 = !{!4} +; FULL-NEXT: !6 = !{!7} +; FULL-NEXT: !7 = distinct !{!7, !8, !"foo: %a"} +; FULL-NEXT: !8 = distinct !{!8, !"foo"} +; FULL-NEXT: !9 = !{!7, !10} +; FULL-NEXT: !10 = distinct !{!10, !8, !"foo: %c"} +; FULL-NEXT: !11 = !{!10} +; FULL-NEXT: !12 = !{!13} +; FULL-NEXT: !13 = distinct !{!13, !14, !"hello: %a"} +; FULL-NEXT: !14 = distinct !{!14, !"hello"} +; FULL-NEXT: !15 = !{!13, !16, !7, !10} +; FULL-NEXT: !16 = distinct !{!16, !14, !"hello: %c"} +; FULL-NEXT: !17 = !{!16} +; FULL-NEXT: !18 = !{!19} +; FULL-NEXT: !19 = distinct !{!19, !20, !"hello2: %a"} +; FULL-NEXT: !20 = distinct !{!20, !"hello2"} +; FULL-NEXT: !21 = !{!19, !22} +; FULL-NEXT: !22 = distinct !{!22, !20, !"hello2: %b"} +; FULL-NEXT: !23 = !{!22} Index: llvm/test/Transforms/Inline/parallel-loop-md-merge.ll =================================================================== --- llvm/test/Transforms/Inline/parallel-loop-md-merge.ll +++ llvm/test/Transforms/Inline/parallel-loop-md-merge.ll @@ -1,4 +1,5 @@ -; RUN: opt -always-inline -globalopt -S < %s | FileCheck %s +; RUN: opt -always-inline -globalopt --use-noalias-intrinsic-during-inlining=scopes -S < %s | FileCheck %s --check-prefixes=CHECK +; RUN: opt -always-inline -globalopt --use-noalias-intrinsic-during-inlining=full -S < %s | FileCheck %s --check-prefixes=CHECK ; ; static void __attribute__((always_inline)) callee(long n, double A[static const restrict n], long i) { ; for (long j = 0; j < n; j += 1) @@ -64,15 +65,18 @@ !11 = distinct !{!11, !12} ; LoopID !12 = !{!"llvm.loop.parallel_accesses", !10} +; There is a small reordering when noalias intrinsics are introduced ; CHECK: store double 4.200000e+01, {{.*}} !llvm.access.group ![[ACCESS_GROUP_LIST_3:[0-9]+]] ; CHECK: br label %for.cond.i, !llvm.loop ![[LOOP_INNER:[0-9]+]] ; CHECK: br label %for.cond, !llvm.loop ![[LOOP_OUTER:[0-9]+]] -; CHECK: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_INNER:[0-9]+]], ![[ACCESS_GROUP_OUTER:[0-9]+]]} -; CHECK: ![[ACCESS_GROUP_INNER]] = distinct !{} -; CHECK: ![[ACCESS_GROUP_OUTER]] = distinct !{} -; CHECK: ![[LOOP_INNER]] = distinct !{![[LOOP_INNER]], ![[ACCESSES_INNER:[0-9]+]]} -; CHECK: ![[ACCESSES_INNER]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_INNER]]} -; CHECK: ![[LOOP_OUTER]] = distinct !{![[LOOP_OUTER]], ![[ACCESSES_OUTER:[0-9]+]]} -; CHECK: ![[ACCESSES_OUTER]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_OUTER]]} + +; CHECK-DAG: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_INNER:[0-9]+]], ![[ACCESS_GROUP_OUTER:[0-9]+]]} +; CHECK-DAG: ![[ACCESS_GROUP_INNER]] = distinct !{} +; CHECK-DAG: ![[ACCESS_GROUP_OUTER]] = distinct !{} + +; CHECK-DAG: ![[LOOP_INNER]] = distinct !{![[LOOP_INNER]], ![[ACCESSES_INNER:[0-9]+]]} +; CHECK-DAG: ![[ACCESSES_INNER]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_INNER]]} +; CHECK-DAG: ![[LOOP_OUTER]] = distinct !{![[LOOP_OUTER]], ![[ACCESSES_OUTER:[0-9]+]]} +; CHECK-DAG: ![[ACCESSES_OUTER]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_OUTER]]} Index: llvm/test/Transforms/Inline/pr50589.ll =================================================================== --- llvm/test/Transforms/Inline/pr50589.ll +++ llvm/test/Transforms/Inline/pr50589.ll @@ -18,9 +18,10 @@ ; The load should not have !noalias. define void @caller1(<2 x i8>* %ptr1, <2 x i8>* %ptr2) { ; CHECK-LABEL: @caller1( -; CHECK-NEXT: [[PASSTHRU:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2{{$}} -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]]) -; CHECK-NEXT: store <2 x i8> zeroinitializer, <2 x i8>* [[PTR2]], align 2, !alias.scope !0 +; CHECK-NEXT: [[PASSTHRU:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2 +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0v2i8.i64(<2 x i8>** null, i64 0, metadata [[META0:![0-9]+]]) +; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i8>* @llvm.noalias.p0v2i8.p0i8.p0p0v2i8.i64(<2 x i8>* [[PTR2]], i8* [[TMP1]], <2 x i8>** null, i64 0, metadata [[META0]]), !noalias !0 +; CHECK-NEXT: store <2 x i8> zeroinitializer, <2 x i8>* [[TMP2]], align 2, !noalias !0 ; CHECK-NEXT: ret void ; %passthru = load <2 x i8>, <2 x i8>* %ptr2 @@ -44,9 +45,10 @@ ; The load should not have !noalias. define void @caller2(<2 x i8>* %ptr1, <2 x i8>* %ptr2) { ; CHECK-LABEL: @caller2( -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) -; CHECK-NEXT: [[PASSTHRU_I:%.*]] = load <2 x i8>, <2 x i8>* [[PTR2:%.*]], align 2, !alias.scope !3{{$}} -; CHECK-NEXT: store <2 x i8> zeroinitializer, <2 x i8>* [[PTR2]], align 2, !alias.scope !3 +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0v2i8.i64(<2 x i8>** null, i64 0, metadata [[META3:![0-9]+]]) +; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i8>* @llvm.noalias.p0v2i8.p0i8.p0p0v2i8.i64(<2 x i8>* [[PTR2:%.*]], i8* [[TMP1]], <2 x i8>** null, i64 0, metadata [[META3]]), !noalias !3 +; CHECK-NEXT: [[PASSTHRU_I:%.*]] = load <2 x i8>, <2 x i8>* [[TMP2]], align 2, !noalias !3 +; CHECK-NEXT: store <2 x i8> zeroinitializer, <2 x i8>* [[TMP2]], align 2, !noalias !3 ; CHECK-NEXT: ret void ; call <2 x i8> @callee2(<2 x i8>* %ptr1, <2 x i8>* %ptr2, <2 x i1> zeroinitializer) Index: llvm/test/Transforms/InstCombine/fold-phi-load-metadata.ll =================================================================== --- llvm/test/Transforms/InstCombine/fold-phi-load-metadata.ll +++ llvm/test/Transforms/InstCombine/fold-phi-load-metadata.ll @@ -40,10 +40,10 @@ ; CHECK: ![[TBAA]] = !{![[TAG1:[0-9]+]], ![[TAG1]], i64 0} ; CHECK: ![[TAG1]] = !{!"int", !{{[0-9]+}}, i64 0} ; CHECK: ![[RANGE]] = !{i32 10, i32 25} -; CHECK: ![[ALIAS_SCOPE]] = !{![[SCOPE0:[0-9]+]], ![[SCOPE1:[0-9]+]], ![[SCOPE2:[0-9]+]]} +; CHECK: ![[ALIAS_SCOPE]] = !{![[SCOPE0:[0-9]+]], ![[SCOPE2:[0-9]+]], ![[SCOPE1:[0-9]+]]} ; CHECK: ![[SCOPE0]] = distinct !{![[SCOPE0]], !{{[0-9]+}}, !"scope0"} -; CHECK: ![[SCOPE1]] = distinct !{![[SCOPE1]], !{{[0-9]+}}, !"scope1"} ; CHECK: ![[SCOPE2]] = distinct !{![[SCOPE2]], !{{[0-9]+}}, !"scope2"} +; CHECK: ![[SCOPE1]] = distinct !{![[SCOPE1]], !{{[0-9]+}}, !"scope1"} ; CHECK: ![[NOALIAS]] = !{![[SCOPE3:[0-9]+]]} ; CHECK: ![[SCOPE3]] = distinct !{![[SCOPE3]], !{{[0-9]+}}, !"scope3"} Index: llvm/test/Transforms/InstCombine/noalias.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/InstCombine/noalias.ll @@ -0,0 +1,49 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-p:32:32:32:32:8-s0:32:32-a0:8:8-S32-n32-v128:32:32-P0-p0:32:32:32:32:8-p10:32:32:32:32:8-p20:32:32:32:32:8" + +@__const.f1.i = private unnamed_addr constant { i8*, [4 x i8] } { i8* null, [4 x i8] undef }, align 4 + +declare void @do_something(i8*) + +; Function Attrs: nounwind optsize +define dso_local i64 @test01() local_unnamed_addr #0 { +entry: + %i.sroa.6 = alloca [2 x i8], align 2 + %i.sroa.6.0..sroa_idx6 = getelementptr inbounds [2 x i8], [2 x i8]* %i.sroa.6, i32 0, i32 0 + call void @llvm.lifetime.start.p0i8(i64 2, i8* %i.sroa.6.0..sroa_idx6) + %0 = call i8* @llvm.noalias.decl.p0i8.p0a2i8.i32([2 x i8]* %i.sroa.6, i32 2, metadata !2) + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %i.sroa.6.0..sroa_idx6, i8* align 2 getelementptr inbounds (i8, i8* bitcast ({ i8*, [4 x i8] }* @__const.f1.i to i8*), i32 2), i32 2, i1 false) + %i.sroa.6.cast = bitcast [2 x i8]* %i.sroa.6 to i8* + call void @do_something(i8* %i.sroa.6.cast) + call void @llvm.lifetime.end.p0i8(i64 2, i8* %i.sroa.6.0..sroa_idx6) + ret i64 undef +} + +; CHECK-LABEL: @test01( +; CHECK: %i.sroa.6 = alloca i16, align 2 +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0i16.i32(i16* nonnull %i.sroa.6, i32 2, metadata !2) + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: argmemonly nounwind +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i1 immarg) #1 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0a2i8.i32([2 x i8]*, i32, metadata) #1 + +attributes #0 = { nounwind optsize "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"f1: i"} +!4 = distinct !{!4, !"f1"} Index: llvm/test/Transforms/InstSimplify/noalias.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/InstSimplify/noalias.ll @@ -0,0 +1,172 @@ +; RUN: opt -instsimplify -S < %s | FileCheck %s + +define void @test01(i8* %ptr) { + call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i32(i8* %ptr, i8* null, i8** null, i32 0, metadata !1) + ret void + +; CHECK-LABEL: @test01 +; CHECK-NOT: llvm.noalias.p0i8 +; CHECK: ret void +} + +define i8* @test02() { + %v = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i32(i8* null, i8* null, i8** null, i32 0, metadata !1) + ret i8* %v + +; CHECK-LABEL: @test02 +; CHECK: llvm.noalias.p0i8 +; CHECK: ret i8* %v +} + +define i8* @test03() { + %v = call i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i32(i8* undef, i8* null, i8** null, i32 0, metadata !1) + ret i8* %v + +; CHECK-LABEL: @test03 +; CHECK-NOT: llvm.noalias.p0i8 +; CHECK: ret i8* undef +} + +declare i8* @llvm.noalias.p0i8.p0i8.p0p0i8.i32(i8*, i8*, i8**, i32, metadata ) nounwind + +define void @test11(i8* %ptr) { + call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %ptr, i8* null, i8** null, i8** null, i32 0, metadata !1) + ret void + +; CHECK-LABEL: @test11 +; CHECK-NOT: llvm.provenance.noalias.p0i8 +; CHECK: ret void +} + +define i8* @test12() { + %v = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* null, i8* null, i8** null, i8** null, i32 0, metadata !1) + ret i8* %v + +; CHECK-LABEL: @test12 +; CHECK: llvm.provenance.noalias.p0i8 +; CHECK: ret i8* %v +} + +define i8* @test13() { + %v = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* undef, i8* null, i8** null, i8** null, i32 0, metadata !1) + ret i8* %v + +; CHECK-LABEL: @test13 +; CHECK-NOT: llvm.provenance.noalias.p0i8 +; CHECK: ret i8* undef +} + +define i8* @test14() { + %u = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* null, i8* null, i8** null, i8** null, i32 0, metadata !1) + %v = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %u, i8* null, i8** null, i8** null, i32 0, metadata !1) + ret i8* %v + +; CHECK-LABEL: @test14 +; CHECK: llvm.provenance.noalias.p0i8 +; CHECK-NOT: llvm.provenance.noalias.p0i8 +; CHECK: ret i8* %u +} + +define i8* @test15() { + %u = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* null, i8* null, i8** null, i8** null, i32 1, metadata !1) + %v = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %u, i8* null, i8** null, i8** null, i32 0, metadata !1) + ret i8* %v + +; CHECK-LABEL: @test15 +; CHECK: llvm.provenance.noalias.p0i8 +; CHECK: llvm.provenance.noalias.p0i8 +; CHECK: ret i8* %v +} + +define i8* @test20() { + %u = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* null, i8* null, i8** null, i8** null, i32 0, metadata !1) + %v = call i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8* null, i8* %u) + ret i8* %v + +; CHECK-LABEL: @test20 +; CHECK: llvm.provenance.noalias.p0i8 +; CHECK: llvm.noalias.arg.guard.p0i8 +; CHECK: ret i8* %v +} + +define i8* @test21() { + %u = call i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* null, i8* null, i8** null, i8** null, i32 0, metadata !1) + %v = call i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8* undef, i8* %u) + ret i8* %v + +; CHECK-LABEL: @test21 +; CHECK-NOT: llvm.provenance.noalias.p0i8 +; CHECK-NOT: llvm.noalias.arg.guard.p0i8 +; CHECK: ret i8* undef +} + +define i8* @test30() { + %v = call i8* @llvm.noalias.copy.guard.p0i8.p0i8(i8* null, i8* null, metadata !2, metadata !1) + ret i8* %v + +; CHECK-LABEL: @test30 +; CHECK: llvm.noalias.copy.guard.p0i8 +; CHECK: ret i8* %v +} + +define void @test31() { + %v = call i8* @llvm.noalias.copy.guard.p0i8.p0i8(i8* null, i8* null, metadata !2, metadata !1) + ret void + +; CHECK-LABEL: @test31 +; CHECK-NOT: llvm.noalias.copy.guard.p0i8 +; CHECK: ret void +} + +define i8* @test32() { + %v = call i8* @llvm.noalias.copy.guard.p0i8.p0i8(i8* undef, i8* null, metadata !2, metadata !1) + ret i8* %v + +; CHECK-LABEL: @test32 +; CHECK-NOT: llvm.noalias.copy.guard.p0i8 +; CHECK: ret i8* undef +} + +define void @test40() { + %v = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i8** null, i32 0, metadata !1) + ret void + +; CHECK-LABEL: @test40 +; CHECK-NOT: llvm.noalias.decl.p0i8 +; CHECK: ret void +} + +define void @test41() { + %u = alloca i8* + %v = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i8** %u, i32 0, metadata !4) + ret void + +; CHECK-LABEL: @test41 +; CHECK-NOT: alloca +; CHECK-NOT: llvm.noalias.decl.p0i8 +; CHECK: ret void +} + +define i8** @test42() { + %u = alloca i8* + %v = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i8** %u, i32 0, metadata !0) + ret i8** %u + +; CHECK-LABEL: @test42 +; CHECK: alloca +; CHECK: llvm.noalias.decl.p0i8 +; CHECK: ret i8** %u +} + + +declare i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8*, i8*, i8**, i8**, i32, metadata ) nounwind +declare i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8*, i8*) nounwind readnone +declare i8* @llvm.noalias.copy.guard.p0i8.p0i8(i8*, i8*, metadata, metadata) +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i8**, i32, metadata) argmemonly nounwind + +!0 = !{!0, !"some domain"} +!1 = !{!1, !0, !"some scope"} +!2 = !{!3} +!3 = !{ i64 -1, i64 0 } +!4 = !{!4, !"some other domain"} +!5 = !{!5, !4, !"some other scope"} Index: llvm/test/Transforms/JumpThreading/free_instructions.ll =================================================================== --- llvm/test/Transforms/JumpThreading/free_instructions.ll +++ llvm/test/Transforms/JumpThreading/free_instructions.ll @@ -20,7 +20,7 @@ ; CHECK: else2: ; CHECK-NEXT: store i32 -2, i32* [[P]], align 4 ; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META4:![0-9]+]]) -; CHECK-NEXT: store i32 1, i32* [[P]], align 4, !noalias !4 +; CHECK-NEXT: store i32 1, i32* [[P]], align 4, !noalias [[META4]] ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P]], i64 32) ] ; CHECK-NEXT: store i32 2, i32* [[P]], align 4 ; CHECK-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to i8* Index: llvm/test/Transforms/JumpThreading/noalias-decl.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/JumpThreading/noalias-decl.ll @@ -0,0 +1,74 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -jump-threading < %s | FileCheck %s + +define void @test01(i32* %ptr1, i32* %ptr2) { +; CHECK-LABEL: @test01( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[V1_DECL:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata [[META0:![0-9]+]]) +; CHECK-NEXT: [[V1_PROV:%.*]] = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* [[PTR1:%.*]], i8* [[V1_DECL]], i32** null, i32** null, i32 0, metadata [[META0]]) +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LATCH:%.*]] ] +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[I]], 100 +; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[LATCH]] +; CHECK: latch: +; CHECK-NEXT: [[V2_DECL:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata [[META3:![0-9]+]]) +; CHECK-NEXT: [[V2_PROV:%.*]] = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* [[PTR2:%.*]], i8* [[V2_DECL]], i32** null, i32** null, i32 0, metadata [[META3]]) +; CHECK-NEXT: store i32 0, i32* [[PTR1]], ptr_provenance i32* [[V1_PROV]], align 4, !noalias !0 +; CHECK-NEXT: store i32 1, i32* [[PTR2]], ptr_provenance i32* [[V2_PROV]], align 4, !noalias !3 +; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 +; CHECK-NEXT: br label [[LOOP]] +; CHECK: exit: +; CHECK-NEXT: [[V2_DECL2:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata [[META3]]) +; CHECK-NEXT: [[V2_PROV3:%.*]] = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* [[PTR2]], i8* [[V2_DECL2]], i32** null, i32** null, i32 0, metadata [[META3]]) +; CHECK-NEXT: store i32 0, i32* [[PTR1]], ptr_provenance i32* [[V1_PROV]], align 4, !noalias !0 +; CHECK-NEXT: store i32 1, i32* [[PTR2]], ptr_provenance i32* [[V2_PROV3]], align 4, !noalias !3 +; CHECK-NEXT: ret void +; +entry: + %v1.decl = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !0) + %v1.prov = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %ptr1, i8* %v1.decl, i32** null, i32** null, i32 0, metadata !0) + br label %loop + +loop: + %i = phi i32 [ 0, %entry ], [ %i.inc, %latch ] + %c = icmp eq i32 %i, 100 + br i1 %c, label %if, label %latch + +if: + br label %latch + +latch: + %p = phi i1 [ true, %if ], [ false, %loop ] + %v2.decl = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !3) + %v2.prov = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %ptr2, i8* %v2.decl, i32** null, i32** null, i32 0, metadata !3) + store i32 0, i32* %ptr1, ptr_provenance i32* %v1.prov, !noalias !0 + store i32 1, i32* %ptr2, ptr_provenance i32* %v2.prov, !noalias !3 + ; store i32 2, i32* %ptr2, ptr_provenance i32* %v2.prov, !noalias !5 + %i.inc = add i32 %i, 1 + br i1 %p, label %exit, label %loop + +exit: + ret void +} + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) + +!0 = !{!1} +!1 = distinct !{!1, !2, !"scope1"} +!2 = distinct !{!2, !"domain"} +!3 = !{!4} +!4 = distinct !{!4, !2, !"scope2"} +!5 = !{!1, !4} + +; CHECK: !0 = !{!1} +; CHECK: !1 = distinct !{!1, !2, !"scope1"} +; CHECK: !2 = distinct !{!2, !"domain"} +; CHECK: !3 = !{!4} +; CHECK: !4 = distinct !{!4, !2, !"scope2"} +; CHECK-NOT: = + Index: llvm/test/Transforms/JumpThreading/noalias-scope-decl.ll =================================================================== --- llvm/test/Transforms/JumpThreading/noalias-scope-decl.ll +++ llvm/test/Transforms/JumpThreading/noalias-scope-decl.ll @@ -4,22 +4,22 @@ define void @test(i8* %ptr) { ; CHECK-LABEL: @test( ; CHECK-NEXT: entry: -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !0) +; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]]) ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LATCH:%.*]] ] ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[I]], 100 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[LATCH]] ; CHECK: latch: -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !3) +; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) ; CHECK-NEXT: store i8 0, i8* [[PTR:%.*]], align 1, !noalias !0 ; CHECK-NEXT: store i8 1, i8* [[PTR]], align 1, !noalias !3 ; CHECK-NEXT: [[I_INC]] = add i32 [[I]], 1 ; CHECK-NEXT: br label [[LOOP]] ; CHECK: exit: -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !5) +; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3]]) ; CHECK-NEXT: store i8 0, i8* [[PTR]], align 1, !noalias !0 -; CHECK-NEXT: store i8 1, i8* [[PTR]], align 1, !noalias !5 +; CHECK-NEXT: store i8 1, i8* [[PTR]], align 1, !noalias !3 ; CHECK-NEXT: ret void ; entry: @@ -59,5 +59,4 @@ ; CHECK: !2 = distinct !{!2, !"domain"} ; CHECK: !3 = !{!4} ; CHECK: !4 = distinct !{!4, !2, !"scope2"} -; CHECK: !5 = !{!6} -; CHECK: !6 = distinct !{!6, !2, !"scope2:thread"} +; CHECK-NOT: = Index: llvm/test/Transforms/LICM/noalias.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LICM/noalias.ll @@ -0,0 +1,142 @@ +; RUN: opt -S -basic-aa -licm %s | FileCheck -check-prefixes=CHECK,MSSA %s +; RUN: opt -aa-pipeline=basic-aa -passes='require,require,require,require,loop-mssa(licm)' < %s -S | FileCheck -check-prefixes=CHECK,MSSA %s + +; Function Attrs: nounwind +define dso_local void @test01(i32* %_p, i32 %n) #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + br label %do.body + +do.body: ; preds = %do.body, %entry + %n.addr.0 = phi i32 [ %n, %entry ], [ %dec, %do.body ] + %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_p, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 42, i32* %_p, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + %dec = add nsw i32 %n.addr.0, -1 + %cmp = icmp ne i32 %dec, 0 + br i1 %cmp, label %do.body, label %do.end + +do.end: ; preds = %do.body + ret void +} + +; CHECK-LABEL: @test01( +; CHECK-LABEL: entry: +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) +; CHECK: %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_p, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 +; MSSA: store i32 42, i32* %_p, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 +; CHECK-LABEL: do.body: +; CHECK-LABEL: do.end: +; AST: store i32 42, i32* %_p, align 4, !tbaa !9 +; CHECK: ret void + +; Function Attrs: nounwind +define dso_local void @test02(i32* %_p, i32 %n) #0 { +entry: + br label %do.body + +do.body: ; preds = %do.body, %entry + %n.addr.0 = phi i32 [ %n, %entry ], [ %dec, %do.body ] + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) + %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_p, i8* %0, i32** null, i32** undef, i32 0, metadata !11), !tbaa !5, !noalias !11 + store i32 42, i32* %_p, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !11 + %dec = add nsw i32 %n.addr.0, -1 + %cmp = icmp ne i32 %dec, 0 + br i1 %cmp, label %do.body, label %do.end + +do.end: ; preds = %do.body + ret void +} + +; CHECK-LABEL: @test02( +; CHECK-LABEL: entry: +; CHECK-LABEL: do.body: +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) +; CHECK: %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_p, i8* %0, i32** null, i32** undef, i32 0, metadata !11), !tbaa !5, !noalias !11 +; CHECK-LABEL: do.end: +; CHECK: store i32 42, i32* %_p, align 4, !tbaa !9 +; CHECK: ret void + +%struct.d = type { i8* } +%struct.f = type { i8* } + +; Function Attrs: nofree nounwind +define dso_local void @test03(%struct.d* nocapture readonly %h, %struct.f* %j) local_unnamed_addr addrspace(1) #0 !noalias !14 { +entry: + %e = getelementptr inbounds %struct.d, %struct.d* %h, i32 0, i32 0 + %0 = load i8*, i8** %e, align 4, !tbaa !17, !noalias !14 + %1 = tail call addrspace(1) i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %0, i8* null, i8** nonnull %e, i8** undef, i32 0, metadata !14), !tbaa !17, !noalias !14 + %e1 = getelementptr inbounds %struct.f, %struct.f* %j, i32 0, i32 0 + %e1.promoted = load i8*, i8** %e1, align 4, !tbaa !19, !noalias !14 + br label %for.body + +for.cond.cleanup: ; preds = %for.body + %add.ptr.guard.guard.guard.lcssa = phi i8* [ %add.ptr.guard.guard.guard, %for.body ] + store i8* %add.ptr.guard.guard.guard.lcssa, i8** %e1, align 4, !tbaa !19, !noalias !14 + ret void + +for.body: ; preds = %entry, %for.body + %add.ptr.guard.guard.guard8 = phi i8* [ %e1.promoted, %entry ], [ %add.ptr.guard.guard.guard, %for.body ] + %i.07 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %2 = tail call addrspace(1) i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %add.ptr.guard.guard.guard8, i8* null, i8** nonnull %e1, i8** undef, i32 0, metadata !14), !tbaa !19, !noalias !14 + %.unpack.unpack = load i8, i8* %0, ptr_provenance i8* %1, align 1, !tbaa !21, !noalias !14 + store i8 %.unpack.unpack, i8* %add.ptr.guard.guard.guard8, ptr_provenance i8* %2, align 1, !tbaa !21, !noalias !14 + %add.ptr = getelementptr inbounds i8, i8* %add.ptr.guard.guard.guard8, i32 2 + %add.ptr.guard.guard.guard = tail call addrspace(1) i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8* nonnull %add.ptr, i8* %2) + %inc = add nuw nsw i32 %i.07, 1 + %cmp = icmp ult i32 %i.07, 55 + br i1 %cmp, label %for.body, label %for.cond.cleanup +} + +; CHECK-LABEL: @test03 +; CHECK: entry: +; CHECK: @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %0, i8* null, i8** nonnull %e, i8** undef, i32 0, metadata !14), !tbaa !17, !noalias !14 +; CHECK: for.cond.cleanup: +; CHECK: @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %add.ptr.guard.guard.guard8.lcssa, i8* null, i8** nonnull %e1, i8** undef, i32 0, metadata !14), !tbaa !19, !noalias !14 +; CHECK: for.body: +; CHECK: @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %add.ptr.guard.guard.guard8, i8* null, i8** nonnull %e1, i8** undef, i32 0, metadata !14), !tbaa !19, !noalias !14 +; CHECK: } + + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #2 + +; Function Attrs: nounwind readnone speculatable +declare i8* @llvm.provenance.noalias.p0i8.p0i8.p0p0i8.p0p0i8.i32(i8* %0, i8* %1, i8** %2, i8** %3, i32 %4, metadata %5) addrspace(1) #2 + +; Function Attrs: nounwind readnone speculatable +declare i8* @llvm.noalias.arg.guard.p0i8.p0i8(i8* %0, i8* %1) addrspace(1) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test01: rp"} +!4 = distinct !{!4, !"test01"} +!5 = !{!6, !6, i64 0, i64 4} +!6 = !{!7, i64 4, !"any pointer"} +!7 = !{!8, i64 1, !"omnipotent char"} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!7, i64 4, !"int"} +!11 = !{!12} +!12 = distinct !{!12, !13, !"test02: rp"} +!13 = distinct !{!13, !"test02"} +!14 = !{!15} +!15 = distinct !{!15, !16, !"test03: unknown scope"} +!16 = distinct !{!16, !"test03"} +!17 = !{!18, !6, i64 0, i64 4} +!18 = !{!7, i64 4, !"d", !6, i64 0, i64 4} +!19 = !{!20, !6, i64 0, i64 4} +!20 = !{!7, i64 4, !"f", !6, i64 0, i64 4} +!21 = !{!22, !22, i64 0, i64 1} +!22 = !{!7, i64 1, !"b", !23, i64 0, i64 1} +!23 = !{!7, i64 1, !"a"} Index: llvm/test/Transforms/LICM/noalias02.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LICM/noalias02.ll @@ -0,0 +1,45 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -basic-aa -licm -enable-new-pm=0 %s | FileCheck -check-prefixes=CHECK %s +; RUN: opt -aa-pipeline=basic-aa -passes='require,require,require,require,loop-mssa(licm)' < %s -S | FileCheck -check-prefixes=CHECK %s + +; ModuleID = 'zzz_test.ll' +source_filename = "zzz_test.i" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@c = external global i32*, align 8 + +define i32 @f(i32* %p, i1 %b) local_unnamed_addr !noalias !0 { +; CHECK-LABEL: @f( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: br i1 [[B:%.*]], label [[FOR_BODY]], label [[FOR_END:%.*]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK: for.end: +; CHECK-NEXT: [[TMP0:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[P:%.*]], i8* null, i32** @c, i32** undef, i64 0, metadata [[META0:![0-9]+]]), !noalias !0 +; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[P]], ptr_provenance i32* [[TMP0]], align 4, !noalias !0 +; CHECK-NEXT: ret i32 [[TMP1]] +; +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %0 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %p, i8* null, i32** @c, i32** undef, i64 0, metadata !0), !noalias !0 + %1 = load i32, i32* %p, ptr_provenance i32* %0, align 4, !noalias !0 + br i1 %b, label %for.body, label %for.end, !llvm.loop !3 + +for.end: ; preds = %for.body + %.lcssa = phi i32 [ %1, %for.body ] + ret i32 %.lcssa +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32*, i8*, i32**, i32**, i64, metadata) #0 + +attributes #0 = { nofree nosync nounwind readnone speculatable willreturn } + +!0 = !{!1} +!1 = distinct !{!1, !2, !"f: unknown scope"} +!2 = distinct !{!2, !"f"} +!3 = distinct !{!3, !4} +!4 = !{!"llvm.loop.mustprogress"} Index: llvm/test/Transforms/LoopRotate/noalias.ll =================================================================== --- llvm/test/Transforms/LoopRotate/noalias.ll +++ llvm/test/Transforms/LoopRotate/noalias.ll @@ -1,5 +1,5 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -loop-rotate -verify-memoryssa < %s | FileCheck %s -; RUN: opt -S -passes='require,require,loop(loop-rotate)' < %s | FileCheck %s ; RUN: opt -S -passes='require,require,loop(loop-rotate)' -verify-memoryssa < %s | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" @@ -9,15 +9,26 @@ define void @test_02(i32* nocapture %_pA) nounwind ssp { ; CHECK-LABEL: @test_02( -; CHECK: entry: -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !2) -; CHECK: store i32 42, i32* %_pA, align 16, !alias.scope !2 -; CHECK: for.body: -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !5) -; CHECK: store i32 0, i32* %arrayidx, align 16, !noalias !5 -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !7) -; CHECK: store i32 42, i32* %_pA, align 16, !alias.scope !7 -; CHECK: for.end: +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ARRAY:%.*]] = alloca [20 x i32], align 16 +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META2:![0-9]+]]) +; CHECK-NEXT: store i32 42, i32* [[_PA:%.*]], align 16, !alias.scope !2 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [20 x i32], [20 x i32]* [[ARRAY]], i64 0, i64 0 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_01:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) +; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX]], align 16, !noalias !5 +; CHECK-NEXT: [[INC]] = add nsw i32 [[I_01]], 1 +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META7:![0-9]+]]) +; CHECK-NEXT: store i32 42, i32* [[_PA]], align 16, !alias.scope !7 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], 100 +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: [[ARRAYIDX_LCSSA:%.*]] = phi i32* [ [[ARRAYIDX]], [[FOR_BODY]] ] +; CHECK-NEXT: call void @g(i32* [[ARRAYIDX_LCSSA]]) #[[ATTR2:[0-9]+]] +; CHECK-NEXT: ret void +; entry: %array = alloca [20 x i32], align 16 @@ -44,12 +55,23 @@ define void @test_03(i32* nocapture %_pA) nounwind ssp { ; CHECK-LABEL: @test_03( -; CHECK: entry: -; CHECK: for.body: -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !5) -; CHECK: store i32 42, i32* %_pA, align 16, !alias.scope !5 -; CHECK: store i32 0, i32* %arrayidx, align 16, !noalias !5 -; CHECK: for.end: +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ARRAY:%.*]] = alloca [20 x i32], align 16 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [20 x i32], [20 x i32]* [[ARRAY]], i64 0, i64 0 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_01:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META5]]) +; CHECK-NEXT: store i32 42, i32* [[_PA:%.*]], align 16, !alias.scope !5 +; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX]], align 16, !noalias !5 +; CHECK-NEXT: [[INC]] = add nsw i32 [[I_01]], 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], 100 +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: [[ARRAYIDX_LCSSA:%.*]] = phi i32* [ [[ARRAYIDX]], [[FOR_BODY]] ] +; CHECK-NEXT: call void @g(i32* [[ARRAYIDX_LCSSA]]) #[[ATTR2]] +; CHECK-NEXT: ret void +; entry: %array = alloca [20 x i32], align 16 @@ -76,16 +98,27 @@ define void @test_04(i32* nocapture %_pA) nounwind ssp { ; CHECK-LABEL: @test_04( -; CHECK: entry: -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !9) -; CHECK: store i32 42, i32* %_pA, align 16, !alias.scope !9 -; CHECK: for.body: -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !5) -; CHECK: store i32 0, i32* %arrayidx, align 16, !noalias !5 -; CHECK: store i32 43, i32* %_pA, align 16, !alias.scope !5 -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !11) -; CHECK: store i32 42, i32* %_pA, align 16, !alias.scope !11 -; CHECK: for.end: +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ARRAY:%.*]] = alloca [20 x i32], align 16 +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META9:![0-9]+]]) +; CHECK-NEXT: store i32 42, i32* [[_PA:%.*]], align 16, !alias.scope !9 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [20 x i32], [20 x i32]* [[ARRAY]], i64 0, i64 0 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_01:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META5]]) +; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX]], align 16, !noalias !5 +; CHECK-NEXT: store i32 43, i32* [[_PA]], align 16, !alias.scope !5 +; CHECK-NEXT: [[INC]] = add nsw i32 [[I_01]], 1 +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META11:![0-9]+]]) +; CHECK-NEXT: store i32 42, i32* [[_PA]], align 16, !alias.scope !11 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], 100 +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: [[ARRAYIDX_LCSSA:%.*]] = phi i32* [ [[ARRAYIDX]], [[FOR_BODY]] ] +; CHECK-NEXT: call void @g(i32* [[ARRAYIDX_LCSSA]]) #[[ATTR2]] +; CHECK-NEXT: ret void +; entry: %array = alloca [20 x i32], align 16 br label %for.cond @@ -112,17 +145,28 @@ define void @test_05(i32* nocapture %_pA) nounwind ssp { ; CHECK-LABEL: @test_05( -; CHECK: entry: -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !13) -; CHECK: store i32 42, i32* %_pA, align 16, !alias.scope !13 -; CHECK: for.body: -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !5) -; CHECK: store i32 0, i32* %arrayidx, align 16, !noalias !5 -; CHECK: store i32 43, i32* %_pA, align 16, !alias.scope !5 -; CHECK: tail call void @llvm.experimental.noalias.scope.decl(metadata !15) -; CHECK: store i32 42, i32* %_pA, align 16, !alias.scope !15 -; CHECK: for.end: -; CHECK: store i32 44, i32* %_pA, align 16, !alias.scope !5 +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ARRAY:%.*]] = alloca [20 x i32], align 16 +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META13:![0-9]+]]) +; CHECK-NEXT: store i32 42, i32* [[_PA:%.*]], align 16, !alias.scope !13 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [20 x i32], [20 x i32]* [[ARRAY]], i64 0, i64 0 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[I_01:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META5]]) +; CHECK-NEXT: store i32 0, i32* [[ARRAYIDX]], align 16, !noalias !5 +; CHECK-NEXT: store i32 43, i32* [[_PA]], align 16, !alias.scope !5 +; CHECK-NEXT: [[INC]] = add nsw i32 [[I_01]], 1 +; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META15:![0-9]+]]) +; CHECK-NEXT: store i32 42, i32* [[_PA]], align 16, !alias.scope !15 +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC]], 100 +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]] +; CHECK: for.end: +; CHECK-NEXT: [[ARRAYIDX_LCSSA:%.*]] = phi i32* [ [[ARRAYIDX]], [[FOR_BODY]] ] +; CHECK-NEXT: store i32 44, i32* [[_PA]], align 16, !alias.scope !5 +; CHECK-NEXT: call void @g(i32* [[ARRAYIDX_LCSSA]]) #[[ATTR2]] +; CHECK-NEXT: ret void +; entry: %array = alloca [20 x i32], align 16 Index: llvm/test/Transforms/LoopRotate/noalias2.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopRotate/noalias2.ll @@ -0,0 +1,206 @@ +; RUN: opt -S -loop-rotate -verify-memoryssa < %s | FileCheck %s +; RUN: opt -S -passes='require,require,loop(loop-rotate)' -verify-memoryssa < %s | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @g(i32*) + +define void @test_02(i32* nocapture %_pA) nounwind ssp { +entry: + %array = alloca [20 x i32], align 16 + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %prov.p = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %p.decl, i32** null, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 42, i32* %_pA, ptr_provenance i32* %prov.p, align 16 + %cmp = icmp slt i32 %i.0, 100 + %arrayidx = getelementptr inbounds [20 x i32], [20 x i32]* %array, i64 0, i64 0 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + store i32 0, i32* %arrayidx, align 16 + %inc = add nsw i32 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond + %arrayidx.lcssa = phi i32* [ %arrayidx, %for.cond ] + call void @g(i32* %arrayidx.lcssa) nounwind + ret void +} + +; CHECK-LABEL: @test_02( +; CHECK: entry: +; CHECK: %p.decl1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) +; CHECK: %prov.p2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %p.decl1, i32** null, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 +; CHECK: store i32 42, i32* %_pA, ptr_provenance i32* unknown_provenance, align 16 +; CHECK: for.body: +; CHECK: %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !9) +; CHECK: %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) +; CHECK: %prov.p = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** null, i32 0, metadata !11), !tbaa !5, !noalias !11 +; CHECK: store i32 42, i32* %_pA, ptr_provenance i32* %prov.p, align 16 +; CHECK: for.end: + + +define void @test_03(i32* nocapture %_pA) nounwind ssp { +entry: + %array = alloca [20 x i32], align 16 + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %cmp = icmp slt i32 %i.0, 100 + %arrayidx = getelementptr inbounds [20 x i32], [20 x i32]* %array, i64 0, i64 0 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %prov.p = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %p.decl, i32** null, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 42, i32* %_pA, ptr_provenance i32* %prov.p, align 16 + store i32 0, i32* %arrayidx, align 16 + %inc = add nsw i32 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond + %arrayidx.lcssa = phi i32* [ %arrayidx, %for.cond ] + call void @g(i32* %arrayidx.lcssa) nounwind + ret void +} +; CHECK-LABEL: @test_03( +; CHECK: entry: +; CHECK: for.body: +; CHECK: %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !9) +; CHECK: %prov.p = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %p.decl, i32** null, i32** null, i32 0, metadata !9), !tbaa !5, !noalias !9 +; CHECK: store i32 42, i32* %_pA, ptr_provenance i32* %prov.p, align 16 +; CHECK: for.end: + +define void @test_04(i32* nocapture %_pA) nounwind ssp { +entry: + %array = alloca [20 x i32], align 16 + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %prov.p = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %p.decl, i32** null, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 42, i32* %_pA, ptr_provenance i32* %prov.p, align 16 + %cmp = icmp slt i32 %i.0, 100 + %arrayidx = getelementptr inbounds [20 x i32], [20 x i32]* %array, i64 0, i64 0 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + store i32 0, i32* %arrayidx, align 16 + store i32 43, i32* %_pA, ptr_provenance i32* %prov.p, align 16 + %inc = add nsw i32 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond + %arrayidx.lcssa = phi i32* [ %arrayidx, %for.cond ] + call void @g(i32* %arrayidx.lcssa) nounwind + ret void +} +; CHECK-LABEL: @test_04( +; CHECK: entry: +; CHECK: %p.decl1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !13) +; CHECK: %prov.p2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %p.decl1, i32** null, i32** null, i32 0, metadata !13), !tbaa !5, !noalias !13 +; CHECK: store i32 42, i32* %_pA, ptr_provenance i32* unknown_provenance, align 16 +; CHECK: for.body: +; CHECK: %prov.p4 = phi i32* [ %prov.p2, %entry ], [ %prov.p, %for.body ] +; CHECK: %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !9) +; CHECK: store i32 43, i32* %_pA, ptr_provenance i32* %prov.p4, align 16 +; CHECK: %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !15) +; CHECK: %prov.p = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** null, i32 0, metadata !15), !tbaa !5, !noalias !15 +; CHECK: store i32 42, i32* %_pA, ptr_provenance i32* %prov.p, align 16 +; CHECK: for.end: + +define void @test_05(i32* nocapture %_pA) nounwind ssp { +entry: + %array = alloca [20 x i32], align 16 + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %prov.p = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %p.decl, i32** null, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 42, i32* %_pA, ptr_provenance i32* %prov.p, align 16 + %cmp = icmp slt i32 %i.0, 100 + %arrayidx = getelementptr inbounds [20 x i32], [20 x i32]* %array, i64 0, i64 0 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + store i32 0, i32* %arrayidx, align 16 + store i32 43, i32* %_pA, ptr_provenance i32* %prov.p, align 16 + %inc = add nsw i32 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond + %arrayidx.lcssa = phi i32* [ %arrayidx, %for.cond ] + store i32 44, i32* %_pA, ptr_provenance i32* %prov.p, align 16 + call void @g(i32* %arrayidx.lcssa) nounwind + ret void +} +; CHECK-LABEL: @test_05( +; CHECK: entry: +; CHECK: %p.decl1 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !17) +; CHECK: %prov.p2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %p.decl1, i32** null, i32** null, i32 0, metadata !17), !tbaa !5, !noalias !17 +; CHECK: store i32 42, i32* %_pA, ptr_provenance i32* unknown_provenance, align 16 +; CHECK: for.body: +; CHECK: %prov.p4 = phi i32* [ %prov.p2, %entry ], [ %prov.p, %for.body ] +; CHECK: %p.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !9) +; CHECK: store i32 43, i32* %_pA, ptr_provenance i32* %prov.p4, align 16 +; CHECK: %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !19) +; CHECK: %prov.p = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** null, i32 0, metadata !19), !tbaa !5, !noalias !19 +; CHECK: store i32 42, i32* %_pA, ptr_provenance i32* %prov.p, align 16 +; CHECK: for.end: +; CHECK: %prov.p.lcssa = phi i32* [ %prov.p, %for.body ] +; CHECK: store i32 44, i32* %_pA, ptr_provenance i32* %prov.p.lcssa, align 16 + + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test_loop_rotate_XX: pA"} +!4 = distinct !{!4, !"test_loop_rotate_XX"} +!5 = !{!6, !6, i64 0, i64 4} +!6 = !{!7, i64 4, !"any pointer"} +!7 = !{!8, i64 1, !"omnipotent char"} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!7, i64 4, !"int"} + +; CHECK: !0 = !{i32 1, !"wchar_size", i32 4} +; CHECK-NEXT: !1 = !{!"clang"} +; CHECK-NEXT: !2 = !{!3} +; CHECK-NEXT: !3 = distinct !{!3, !4, !"test_loop_rotate_XX: pA:pre.rot"} +; CHECK-NEXT: !4 = distinct !{!4, !"test_loop_rotate_XX"} +; CHECK-NEXT: !5 = !{!6, !6, i64 0, i64 4} +; CHECK-NEXT: !6 = !{!7, i64 4, !"any pointer"} +; CHECK-NEXT: !7 = !{!8, i64 1, !"omnipotent char"} +; CHECK-NEXT: !8 = !{!"Simple C/C++ TBAA"} +; CHECK-NEXT: !9 = !{!10} +; CHECK-NEXT: !10 = distinct !{!10, !4, !"test_loop_rotate_XX: pA"} +; CHECK-NEXT: !11 = !{!12} +; CHECK-NEXT: !12 = distinct !{!12, !4, !"test_loop_rotate_XX: pA:h.rot"} +; CHECK-NEXT: !13 = !{!14} +; CHECK-NEXT: !14 = distinct !{!14, !4, !"test_loop_rotate_XX: pA:pre.rot"} +; CHECK-NEXT: !15 = !{!16} +; CHECK-NEXT: !16 = distinct !{!16, !4, !"test_loop_rotate_XX: pA:h.rot"} +; CHECK-NEXT: !17 = !{!18} +; CHECK-NEXT: !18 = distinct !{!18, !4, !"test_loop_rotate_XX: pA:pre.rot"} +; CHECK-NEXT: !19 = !{!20} +; CHECK-NEXT: !20 = distinct !{!20, !4, !"test_loop_rotate_XX: pA:h.rot"} Index: llvm/test/Transforms/LoopUnroll/noalias.ll =================================================================== --- llvm/test/Transforms/LoopUnroll/noalias.ll +++ llvm/test/Transforms/LoopUnroll/noalias.ll @@ -6,20 +6,20 @@ ; CHECK-NEXT: start: ; CHECK-NEXT: br label [[BODY:%.*]] ; CHECK: body: -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !0) +; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]]) ; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[ADDR1:%.*]], align 4, !alias.scope !0 ; CHECK-NEXT: store i32 [[X]], i32* [[ADDR2:%.*]], align 4, !noalias !0 ; CHECK-NEXT: [[ADDR1I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR1]], i32 1 ; CHECK-NEXT: [[ADDR2I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR2]], i32 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !3) +; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]]) ; CHECK-NEXT: [[X_1:%.*]] = load i32, i32* [[ADDR1I_1]], align 4, !alias.scope !3 ; CHECK-NEXT: store i32 [[X_1]], i32* [[ADDR2I_1]], align 4, !noalias !3 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !5) +; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META5:![0-9]+]]) ; CHECK-NEXT: [[X_2:%.*]] = load i32, i32* [[ADDR1]], align 4, !alias.scope !5 ; CHECK-NEXT: store i32 [[X_2]], i32* [[ADDR2]], align 4, !noalias !5 ; CHECK-NEXT: [[ADDR1I_3:%.*]] = getelementptr inbounds i32, i32* [[ADDR1]], i32 1 ; CHECK-NEXT: [[ADDR2I_3:%.*]] = getelementptr inbounds i32, i32* [[ADDR2]], i32 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !7) +; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META7:![0-9]+]]) ; CHECK-NEXT: [[X_3:%.*]] = load i32, i32* [[ADDR1I_3]], align 4, !alias.scope !7 ; CHECK-NEXT: store i32 [[X_3]], i32* [[ADDR2I_3]], align 4, !noalias !7 ; CHECK-NEXT: ret void @@ -48,21 +48,21 @@ define void @test_outside(i32* %addr1, i32* %addr2) { ; CHECK-LABEL: @test_outside( ; CHECK-NEXT: start: -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata !0) +; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl(metadata [[META9:![0-9]+]]) ; CHECK-NEXT: br label [[BODY:%.*]] ; CHECK: body: -; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[ADDR1:%.*]], align 4, !alias.scope !0 -; CHECK-NEXT: store i32 [[X]], i32* [[ADDR2:%.*]], align 4, !noalias !0 +; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[ADDR1:%.*]], align 4, !alias.scope !9 +; CHECK-NEXT: store i32 [[X]], i32* [[ADDR2:%.*]], align 4, !noalias !9 ; CHECK-NEXT: [[ADDR1I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR1]], i32 1 ; CHECK-NEXT: [[ADDR2I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR2]], i32 1 -; CHECK-NEXT: [[X_1:%.*]] = load i32, i32* [[ADDR1I_1]], align 4, !alias.scope !0 -; CHECK-NEXT: store i32 [[X_1]], i32* [[ADDR2I_1]], align 4, !noalias !0 -; CHECK-NEXT: [[X_2:%.*]] = load i32, i32* [[ADDR1]], align 4, !alias.scope !0 -; CHECK-NEXT: store i32 [[X_2]], i32* [[ADDR2]], align 4, !noalias !0 +; CHECK-NEXT: [[X_1:%.*]] = load i32, i32* [[ADDR1I_1]], align 4, !alias.scope !9 +; CHECK-NEXT: store i32 [[X_1]], i32* [[ADDR2I_1]], align 4, !noalias !9 +; CHECK-NEXT: [[X_2:%.*]] = load i32, i32* [[ADDR1]], align 4, !alias.scope !9 +; CHECK-NEXT: store i32 [[X_2]], i32* [[ADDR2]], align 4, !noalias !9 ; CHECK-NEXT: [[ADDR1I_3:%.*]] = getelementptr inbounds i32, i32* [[ADDR1]], i32 1 ; CHECK-NEXT: [[ADDR2I_3:%.*]] = getelementptr inbounds i32, i32* [[ADDR2]], i32 1 -; CHECK-NEXT: [[X_3:%.*]] = load i32, i32* [[ADDR1I_3]], align 4, !alias.scope !0 -; CHECK-NEXT: store i32 [[X_3]], i32* [[ADDR2I_3]], align 4, !noalias !0 +; CHECK-NEXT: [[X_3:%.*]] = load i32, i32* [[ADDR1I_3]], align 4, !alias.scope !9 +; CHECK-NEXT: store i32 [[X_3]], i32* [[ADDR2I_3]], align 4, !noalias !9 ; CHECK-NEXT: ret void ; start: @@ -93,11 +93,13 @@ !2 = !{!1} ; CHECK: !0 = !{!1} -; CHECK: !1 = distinct !{!1, !2} -; CHECK: !2 = distinct !{!2} -; CHECK: !3 = !{!4} -; CHECK: !4 = distinct !{!4, !2, !"It1"} -; CHECK: !5 = !{!6} -; CHECK: !6 = distinct !{!6, !2, !"It2"} -; CHECK: !7 = !{!8} -; CHECK: !8 = distinct !{!8, !2, !"It3"} +; CHECK-NEXT: !1 = distinct !{!1, !2, !"It0"} +; CHECK-NEXT: !2 = distinct !{!2} +; CHECK-NEXT: !3 = !{!4} +; CHECK-NEXT: !4 = distinct !{!4, !2, !"It1"} +; CHECK-NEXT: !5 = !{!6} +; CHECK-NEXT: !6 = distinct !{!6, !2, !"It2"} +; CHECK-NEXT: !7 = !{!8} +; CHECK-NEXT: !8 = distinct !{!8, !2, !"It3"} +; CHECK-NEXT: !9 = !{!10} +; CHECK-NEXT: !10 = distinct !{!10, !2} Index: llvm/test/Transforms/LoopUnroll/noalias2.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopUnroll/noalias2.ll @@ -0,0 +1,196 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -S -unroll-runtime -unroll-count=2 -loop-unroll | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind +define dso_local void @test_loop_unroll_01(i32* nocapture %_pA) local_unnamed_addr #0 { +; CHECK-LABEL: @test_loop_unroll_01( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata [[META2:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* [[_PA:%.*]], i8* [[TMP0]], i32** null, i32** undef, i32 0, metadata [[META2]]), !tbaa [[TBAA5:![0-9]+]], !noalias !2 +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.cond.cleanup: +; CHECK-NEXT: ret void +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_1:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[_PA]], i32 [[I_06]] +; CHECK-NEXT: store i32 [[I_06]], i32* [[ARRAYIDX]], ptr_provenance i32* [[TMP1]], align 4, !tbaa [[TBAA9:![0-9]+]], !noalias !2 +; CHECK-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_06]], 1 +; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[_PA]], i32 [[INC]] +; CHECK-NEXT: store i32 [[INC]], i32* [[ARRAYIDX_1]], ptr_provenance i32* [[TMP1]], align 4, !tbaa [[TBAA9]], !noalias !2 +; CHECK-NEXT: [[INC_1]] = add nuw nsw i32 [[INC]], 1 +; CHECK-NEXT: [[EXITCOND_1:%.*]] = icmp eq i32 [[INC_1]], 4 +; CHECK-NEXT: br i1 [[EXITCOND_1]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]] +; +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + br label %for.body + +for.cond.cleanup: ; preds = %for.body + ret void + +for.body: ; preds = %for.body, %entry + %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %arrayidx = getelementptr inbounds i32, i32* %_pA, i32 %i.06 + store i32 %i.06, i32* %arrayidx, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + %inc = add nuw nsw i32 %i.06, 1 + %exitcond = icmp eq i32 %inc, 4 + br i1 %exitcond, label %for.cond.cleanup, label %for.body +} + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +; Function Attrs: nounwind +define dso_local void @test_loop_unroll_02(i32* nocapture %_pA) local_unnamed_addr #0 { +; CHECK-LABEL: @test_loop_unroll_02( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.cond.cleanup: +; CHECK-NEXT: ret void +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_1:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata [[META13:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* [[_PA:%.*]], i8* [[TMP0]], i32** null, i32** undef, i32 0, metadata [[META13]]), !tbaa [[TBAA5]], !noalias !13 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[_PA]], i32 [[I_06]] +; CHECK-NEXT: store i32 [[I_06]], i32* [[ARRAYIDX]], ptr_provenance i32* [[TMP1]], align 4, !tbaa [[TBAA9]], !noalias !13 +; CHECK-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_06]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata [[META16:![0-9]+]]) +; CHECK-NEXT: [[TMP3:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* [[_PA]], i8* [[TMP2]], i32** null, i32** undef, i32 0, metadata [[META16]]), !tbaa [[TBAA5]], !noalias !16 +; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[_PA]], i32 [[INC]] +; CHECK-NEXT: store i32 [[INC]], i32* [[ARRAYIDX_1]], ptr_provenance i32* [[TMP3]], align 4, !tbaa [[TBAA9]], !noalias !16 +; CHECK-NEXT: [[INC_1]] = add nuw nsw i32 [[INC]], 1 +; CHECK-NEXT: [[EXITCOND_1:%.*]] = icmp eq i32 [[INC_1]], 4 +; CHECK-NEXT: br i1 [[EXITCOND_1]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]] +; +entry: + br label %for.body + +for.cond.cleanup: ; preds = %for.body + ret void + +for.body: ; preds = %for.body, %entry + %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !11), !tbaa !5, !noalias !11 + %arrayidx = getelementptr inbounds i32, i32* %_pA, i32 %i.06 + store i32 %i.06, i32* %arrayidx, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !11 + %inc = add nuw nsw i32 %i.06, 1 + %exitcond = icmp eq i32 %inc, 4 + br i1 %exitcond, label %for.cond.cleanup, label %for.body +} + +; Function Attrs: nounwind +define dso_local void @test_loop_unroll_03(i32* nocapture %_pA, i1 %c) local_unnamed_addr #0 { +; CHECK-LABEL: @test_loop_unroll_03( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.cond.cleanup: +; CHECK-NEXT: ret void +; CHECK: for.body: +; CHECK-NEXT: [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_1:%.*]], [[FOR_BODY1_1:%.*]] ] +; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata [[META19:![0-9]+]]) +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[_PA:%.*]], i32 [[I_06]] +; CHECK-NEXT: br i1 [[C:%.*]], label [[ALT_EXIT:%.*]], label [[FOR_BODY1:%.*]] +; CHECK: for.body1: +; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX]], align 4, !tbaa [[TBAA9]], !noalias !19 +; CHECK-NEXT: [[INC:%.*]] = add nuw nsw i32 [[I_06]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata [[META22:![0-9]+]]) +; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[_PA]], i32 [[INC]] +; CHECK-NEXT: br i1 [[C]], label [[ALT_EXIT]], label [[FOR_BODY1_1]] +; CHECK: for.body1.1: +; CHECK-NEXT: store i32 1, i32* [[ARRAYIDX_1]], align 4, !tbaa [[TBAA9]], !noalias !22 +; CHECK-NEXT: [[INC_1]] = add nuw nsw i32 [[INC]], 1 +; CHECK-NEXT: [[EXITCOND_1:%.*]] = icmp eq i32 [[INC_1]], 4 +; CHECK-NEXT: br i1 [[EXITCOND_1]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]] +; CHECK: alt.exit: +; CHECK-NEXT: [[I_06_LCSSA:%.*]] = phi i32 [ [[I_06]], [[FOR_BODY]] ], [ [[INC]], [[FOR_BODY1]] ] +; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi i8* [ [[TMP0]], [[FOR_BODY]] ], [ [[TMP1]], [[FOR_BODY1]] ] +; CHECK-NEXT: [[ARRAYIDX_LCSSA:%.*]] = phi i32* [ [[ARRAYIDX]], [[FOR_BODY]] ], [ [[ARRAYIDX_1]], [[FOR_BODY1]] ] +; CHECK-NEXT: [[TMP2:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata [[META25:![0-9]+]]) +; CHECK-NEXT: [[S:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* [[_PA]], i8* [[TMP2]], i32** null, i32** undef, i32 0, metadata [[META25]]), !tbaa [[TBAA5]], !noalias [[META25]] +; CHECK-NEXT: store i32 [[I_06_LCSSA]], i32* [[ARRAYIDX_LCSSA]], ptr_provenance i32* [[S]], align 4, !tbaa [[TBAA9]], !noalias [[META25]] +; CHECK-NEXT: ret void +; +entry: + br label %for.body + +for.cond.cleanup: ; preds = %for.body + ret void + +for.body: ; preds = %for.body, %entry + %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body1 ] + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !14) + %arrayidx = getelementptr inbounds i32, i32* %_pA, i32 %i.06 + br i1 %c, label %alt.exit, label %for.body1 + +for.body1: + store i32 1, i32* %arrayidx, align 4, !tbaa !9, !noalias !14 + %inc = add nuw nsw i32 %i.06, 1 + %exitcond = icmp eq i32 %inc, 4 + br i1 %exitcond, label %for.cond.cleanup, label %for.body + +alt.exit: + %s = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !14), !tbaa !5, !noalias !14 + store i32 %i.06, i32* %arrayidx, ptr_provenance i32* %s, align 4, !tbaa !9, !noalias !14 + ret void +} + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test_loop_unroll_01: pA"} +!4 = distinct !{!4, !"test_loop_unroll_01"} +!5 = !{!6, !6, i64 0, i64 4} +!6 = !{!7, i64 4, !"any pointer"} +!7 = !{!8, i64 1, !"omnipotent char"} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!7, i64 4, !"int"} +!11 = !{!12} +!12 = distinct !{!12, !13, !"test_loop_unroll_02: pA"} +!13 = distinct !{!13, !"test_loop_unroll_02"} +!14 = !{!15} +!15 = distinct !{!15, !16, !"test_loop_unroll_03: pA"} +!16 = distinct !{!16, !"test_loop_unroll_03"} + +; CHECK: !0 = !{i32 1, !"wchar_size", i32 4} +; CHECK: !1 = !{!"clang"} +; CHECK: [[META2]] = !{!3} +; CHECK: !3 = distinct !{!3, !4, !"test_loop_unroll_01: pA"} +; CHECK: !4 = distinct !{!4, !"test_loop_unroll_01"} +; CHECK: !5 = !{!6, !6, i64 0, i64 4} +; CHECK: !6 = !{!7, i64 4, !"any pointer"} +; CHECK: !7 = !{!8, i64 1, !"omnipotent char"} +; CHECK: !8 = !{!"Simple C/C++ TBAA"} +; CHECK: !9 = !{!10, !10, i64 0, i64 4} +; CHECK: !10 = !{!7, i64 4, !"int"} +; CHECK: !11 = distinct !{!11, !12} +; CHECK: !12 = !{!"llvm.loop.unroll.disable"} +; CHECK: [[META13]] = !{!14} +; CHECK: !14 = distinct !{!14, !15, !"test_loop_unroll_02: pA:It0"} +; CHECK: !15 = distinct !{!15, !"test_loop_unroll_02"} +; CHECK: [[META16]] = !{!17} +; CHECK: !17 = distinct !{!17, !15, !"test_loop_unroll_02: pA:It1"} +; CHECK: !18 = distinct !{!18, !12} +; CHECK: [[META19]] = !{!20} +; CHECK: !20 = distinct !{!20, !21, !"test_loop_unroll_03: pA:It0"} +; CHECK: !21 = distinct !{!21, !"test_loop_unroll_03"} +; CHECK: [[META22]] = !{!23} +; CHECK: !23 = distinct !{!23, !21, !"test_loop_unroll_03: pA:It1"} +; CHECK: !24 = distinct !{!24, !12} +; CHECK: [[META25]] = !{!26} +; CHECK: !26 = distinct !{!26, !21, !"test_loop_unroll_03: pA"} Index: llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll =================================================================== --- llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll +++ llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl.ll @@ -141,7 +141,7 @@ ; CHECK: !4 = distinct !{!4, !2, !"foo: %inner.result:Peel0"} ; CHECK: !5 = !{!4, !1} ; CHECK: !6 = !{!7} -; CHECK: !7 = distinct !{!7, !2, !"foo: %inner.result"} +; CHECK: !7 = distinct !{!7, !2, !"foo: %inner.result:NotPeeled"} ; CHECK: !8 = !{!7, !1} ; CHECK: !9 = distinct !{!9, !10, !11, !12} ; CHECK: !10 = !{!"llvm.loop.mustprogress"} Index: llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl2.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopUnroll/peel-loop-noalias-scope-decl2.ll @@ -0,0 +1,112 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; ModuleID = 'zzz_test.ll' +; RUN: opt < %s -S -loop-unroll -unroll-force-peel-count=1 | FileCheck %s +; RUN: opt < %s -S -passes='loop-unroll' -unroll-force-peel-count=1 | FileCheck %s +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@b = external local_unnamed_addr global i32, align 4 + +; Function Attrs: nofree nosync nounwind uwtable +define i32 @f() local_unnamed_addr #0 { +; CHECK-LABEL: @f( +; CHECK-NEXT: g.preheader: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @b, align 4, !tbaa [[TBAA0:![0-9]+]] +; CHECK-NEXT: [[CMP_NOT4:%.*]] = icmp slt i32 undef, [[TMP0]] +; CHECK-NEXT: br label [[IF_THEN_PREHEADER:%.*]] +; CHECK: if.then.preheader: +; CHECK-NEXT: br label [[IF_THEN_PEEL_BEGIN:%.*]] +; CHECK: if.then.peel.begin: +; CHECK-NEXT: br label [[IF_THEN_PEEL:%.*]] +; CHECK: if.then.peel: +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META4:![0-9]+]]) +; CHECK-NEXT: [[CONV_PEEL:%.*]] = sext i32 [[TMP0]] to i64 +; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[CONV_PEEL]] to i32* +; CHECK-NEXT: [[CMP_NOT_PEEL:%.*]] = icmp slt i32 undef, 1 +; CHECK-NEXT: br i1 [[CMP_NOT_PEEL]], label [[G_IF_END_CRIT_EDGE:%.*]], label [[IF_THEN_PEEL_NEXT:%.*]] +; CHECK: if.then.peel.next: +; CHECK-NEXT: br label [[IF_THEN_PEEL_NEXT1:%.*]] +; CHECK: if.then.peel.next1: +; CHECK-NEXT: br label [[IF_THEN_PREHEADER_PEEL_NEWPH:%.*]] +; CHECK: if.then.preheader.peel.newph: +; CHECK-NEXT: br label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META7:![0-9]+]]) +; CHECK-NEXT: br i1 false, label [[G_IF_END_CRIT_EDGE_LOOPEXIT:%.*]], label [[IF_THEN]], !llvm.loop [[LOOP9:![0-9]+]] +; CHECK: g.if.end_crit_edge.loopexit: +; CHECK-NEXT: [[DOTLCSSA5_PH:%.*]] = phi i8* [ [[TMP3]], [[IF_THEN]] ] +; CHECK-NEXT: [[DOTLCSSA_PH:%.*]] = phi i32* [ inttoptr (i64 1 to i32*), [[IF_THEN]] ] +; CHECK-NEXT: br label [[G_IF_END_CRIT_EDGE]] +; CHECK: g.if.end_crit_edge: +; CHECK-NEXT: [[DOTLCSSA5:%.*]] = phi i8* [ [[TMP1]], [[IF_THEN_PEEL]] ], [ [[DOTLCSSA5_PH]], [[G_IF_END_CRIT_EDGE_LOOPEXIT]] ] +; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi i32* [ [[TMP2]], [[IF_THEN_PEEL]] ], [ [[DOTLCSSA_PH]], [[G_IF_END_CRIT_EDGE_LOOPEXIT]] ] +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META12:![0-9]+]]) +; CHECK-NEXT: [[TMP5:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[DOTLCSSA]], i8* [[TMP4]], i32** null, i32** undef, i64 0, metadata [[META12]]), !noalias !12 +; CHECK-NEXT: [[DOTGUARD_GUARD:%.*]] = tail call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* [[DOTLCSSA]], i32* [[TMP5]]) +; CHECK-NEXT: [[TMP6:%.*]] = ptrtoint i32* [[DOTGUARD_GUARD]] to i64 +; CHECK-NEXT: [[TMP7:%.*]] = trunc i64 [[TMP6]] to i32 +; CHECK-NEXT: store i32 1, i32* @b, align 4, !tbaa [[TBAA0]] +; CHECK-NEXT: ret i32 undef +; +g.preheader: + %0 = load i32, i32* @b, align 4, !tbaa !0 + %cmp.not4 = icmp slt i32 undef, %0 + br label %if.then.preheader + +if.then.preheader: ; preds = %g.preheader + br label %if.then + +if.then: ; preds = %if.then, %if.then.preheader + %1 = phi i32 [ 1, %if.then ], [ %0, %if.then.preheader ] + %2 = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !4) + %conv = sext i32 %1 to i64 + %3 = inttoptr i64 %conv to i32* + %cmp.not = icmp slt i32 undef, 1 + br i1 %cmp.not, label %g.if.end_crit_edge, label %if.then + +g.if.end_crit_edge: ; preds = %if.then + %.lcssa5 = phi i8* [ %2, %if.then ] + %.lcssa = phi i32* [ %3, %if.then ] + %4 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %.lcssa, i8* %.lcssa5, i32** null, i32** undef, i64 0, metadata !4), !noalias !4 + %.guard.guard = tail call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %.lcssa, i32* %4) + %5 = ptrtoint i32* %.guard.guard to i64 + %6 = trunc i64 %5 to i32 + store i32 1, i32* @b, align 4, !tbaa !0 + ret i32 undef +} + +; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32**, i64, metadata) #1 + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32*, i8*, i32**, i32**, i64, metadata) #2 + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32*, i32*) #2 + +attributes #0 = { nofree nosync nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { inaccessiblememonly nofree nosync nounwind willreturn } +attributes #2 = { nofree nosync nounwind readnone speculatable willreturn } + +!0 = !{!1, !1, i64 0} +!1 = !{!"int", !2, i64 0} +!2 = !{!"omnipotent char", !3, i64 0} +!3 = !{!"Simple C/C++ TBAA"} +!4 = !{!5} +!5 = distinct !{!5, !6, !"f: h"} +!6 = distinct !{!6, !"f"} + +; CHECK: !0 = !{!1, !1, i64 0} +; CHECK: !1 = !{!"int", !2, i64 0} +; CHECK: !2 = !{!"omnipotent char", !3, i64 0} +; CHECK: !3 = !{!"Simple C/C++ TBAA"} +; CHECK: !4 = !{!5} +; CHECK: !5 = distinct !{!5, !6, !"f: h:Peel0"} +; CHECK: !6 = distinct !{!6, !"f"} +; CHECK: !7 = !{!8} +; CHECK: !8 = distinct !{!8, !6, !"f: h:NotPeeled"} +; CHECK: !9 = distinct !{!9, !10, !11} +; CHECK: !10 = !{!"llvm.loop.peeled.count", i32 1} +; CHECK: !11 = !{!"llvm.loop.unroll.disable"} +; CHECK: !12 = !{!13} +; CHECK: !13 = distinct !{!13, !6, !"f: h"} Index: llvm/test/Transforms/LoopVectorize/noalias.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopVectorize/noalias.ll @@ -0,0 +1,90 @@ +; RUN: opt -S -loop-vectorize -force-vector-width=2 -force-vector-interleave=1 < %s | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" + +; Make sure we can vectorize loops which contain noalias intrinsics + + +; A not-used llvm.noalias should not interfere +; CHECK-LABEL: @test_noalias_not_connected( +; CHECK: @llvm.noalias.p0i32 +; CHECK: store <2 x i32> +; CHECK: ret +define void @test_noalias_not_connected(i32 *%d) { +entry: + br label %for.body + +for.body: + %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] + %d2 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %d, i8* null, i32** null, i32 0, metadata !1) + %arrayidx = getelementptr inbounds i32, i32* %d, i64 %indvars.iv + %v1 = load i32, i32* %arrayidx, align 8 + store i32 100, i32* %arrayidx, align 8 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp ne i32 %lftr.wideiv, 128 + br i1 %exitcond, label %for.body, label %for.end + +for.end: + ret void +} + +; A used llvm.noalias should block vectorization. +; CHECK-LABEL: @test_noalias_connected( +; CHECK: @llvm.noalias.p0i32 +; CHECK-NOT: store <2 x i32> +; CHECK: ret +define void @test_noalias_connected(i32 *%d) { +entry: + br label %for.body + +for.body: + %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] + %d2 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %d, i8* null, i32** null, i32 0, metadata !1) + %arrayidx = getelementptr inbounds i32, i32* %d2, i64 %indvars.iv + %v1 = load i32, i32* %arrayidx, align 8 + store i32 100, i32* %arrayidx, align 8 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp ne i32 %lftr.wideiv, 128 + br i1 %exitcond, label %for.body, label %for.end + +for.end: + ret void +} + +; A used llvm.provenance.noalias should NOT block vectorization. +; CHECK-LABEL: @test_provenance.noalias( +; CHECK: @llvm.provenance.noalias.p0i32 +; NOTE: the ptr_provenance is omitted +; CHECK: store <2 x i32> , <2 x i32>* {{%[0-9.a-zA-Z]*}}, align 8 +; CHECK: ret + +define void @test_provenance.noalias(i32 *%d) { +entry: + br label %for.body + +for.body: + %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] + %prov.d = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %d, i8* null, i32** null, i32** null, i32 0, metadata !1) + %arrayidx = getelementptr inbounds i32, i32* %d, i64 %indvars.iv + %v1 = load i32, i32* %arrayidx, ptr_provenance i32* %prov.d, align 8 + store i32 100, i32* %arrayidx, ptr_provenance i32* %prov.d, align 8 + %indvars.iv.next = add i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp ne i32 %lftr.wideiv, 128 + br i1 %exitcond, label %for.body, label %for.end + +for.end: + ret void +} + +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i8**, i32, metadata) argmemonly nounwind +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata ) nounwind +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata ) nounwind + + +;declare i32* @llvm.noalias.p0i32(i32*, metadata) nounwind argmemonly + +!0 = !{!0, !"some domain"} +!1 = !{!1, !0, !"some scope"} Index: llvm/test/Transforms/PhaseOrdering/pr39282.ll =================================================================== --- llvm/test/Transforms/PhaseOrdering/pr39282.ll +++ llvm/test/Transforms/PhaseOrdering/pr39282.ll @@ -18,24 +18,32 @@ define void @pr39282(i32* %addr1, i32* %addr2) { ; CHECK-LABEL: @pr39282( ; CHECK-NEXT: start: -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[X_I:%.*]] = load i32, i32* [[ADDR1:%.*]], align 4, !alias.scope !3, !noalias !0 -; CHECK-NEXT: store i32 [[X_I]], i32* [[ADDR2:%.*]], align 4, !alias.scope !0, !noalias !3 +; CHECK-NEXT: [[TMP0:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META0:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[ADDR2:%.*]], i8* [[TMP0]], i32** null, i32** undef, i64 0, metadata [[META0]]), !noalias !3 +; CHECK-NEXT: [[TMP2:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META5:![0-9]+]]) +; CHECK-NEXT: [[TMP3:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[ADDR1:%.*]], i8* [[TMP2]], i32** null, i32** undef, i64 0, metadata [[META5]]), !noalias !3 +; CHECK-NEXT: [[X_I:%.*]] = load i32, i32* [[ADDR1]], ptr_provenance i32* [[TMP3]], align 4, !noalias !3 +; CHECK-NEXT: store i32 [[X_I]], i32* [[ADDR2]], ptr_provenance i32* [[TMP1]], align 4, !noalias !3 ; CHECK-NEXT: [[ADDR1I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR1]], i64 1 ; CHECK-NEXT: [[ADDR2I_1:%.*]] = getelementptr inbounds i32, i32* [[ADDR2]], i64 1 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[X_I_1:%.*]] = load i32, i32* [[ADDR1I_1]], align 4, !alias.scope !7, !noalias !5 -; CHECK-NEXT: store i32 [[X_I_1]], i32* [[ADDR2I_1]], align 4, !alias.scope !5, !noalias !7 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[X_I_2:%.*]] = load i32, i32* [[ADDR1]], align 4, !alias.scope !11, !noalias !9 -; CHECK-NEXT: store i32 [[X_I_2]], i32* [[ADDR2]], align 4, !alias.scope !9, !noalias !11 -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: call void @llvm.experimental.noalias.scope.decl -; CHECK-NEXT: [[X_I_3:%.*]] = load i32, i32* [[ADDR1I_1]], align 4, !alias.scope !15, !noalias !13 -; CHECK-NEXT: store i32 [[X_I_3]], i32* [[ADDR2I_1]], align 4, !alias.scope !13, !noalias !15 +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META6:![0-9]+]]) +; CHECK-NEXT: [[TMP5:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR2I_1]], i8* [[TMP4]], i32** null, i32** undef, i64 0, metadata [[META6]]), !noalias !8 +; CHECK-NEXT: [[TMP6:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META10:![0-9]+]]) +; CHECK-NEXT: [[TMP7:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR1I_1]], i8* [[TMP6]], i32** null, i32** undef, i64 0, metadata [[META10]]), !noalias !8 +; CHECK-NEXT: [[X_I_1:%.*]] = load i32, i32* [[ADDR1I_1]], ptr_provenance i32* [[TMP7]], align 4, !noalias !8 +; CHECK-NEXT: store i32 [[X_I_1]], i32* [[ADDR2I_1]], ptr_provenance i32* [[TMP5]], align 4, !noalias !8 +; CHECK-NEXT: [[TMP8:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META11:![0-9]+]]) +; CHECK-NEXT: [[TMP9:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR2]], i8* [[TMP8]], i32** null, i32** undef, i64 0, metadata [[META11]]), !noalias !13 +; CHECK-NEXT: [[TMP10:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META15:![0-9]+]]) +; CHECK-NEXT: [[TMP11:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR1]], i8* [[TMP10]], i32** null, i32** undef, i64 0, metadata [[META15]]), !noalias !13 +; CHECK-NEXT: [[X_I_2:%.*]] = load i32, i32* [[ADDR1]], ptr_provenance i32* [[TMP11]], align 4, !noalias !13 +; CHECK-NEXT: store i32 [[X_I_2]], i32* [[ADDR2]], ptr_provenance i32* [[TMP9]], align 4, !noalias !13 +; CHECK-NEXT: [[TMP12:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META16:![0-9]+]]) +; CHECK-NEXT: [[TMP13:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR2I_1]], i8* [[TMP12]], i32** null, i32** undef, i64 0, metadata [[META16]]), !noalias !18 +; CHECK-NEXT: [[TMP14:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META20:![0-9]+]]) +; CHECK-NEXT: [[TMP15:%.*]] = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* nonnull [[ADDR1I_1]], i8* [[TMP14]], i32** null, i32** undef, i64 0, metadata [[META20]]), !noalias !18 +; CHECK-NEXT: [[X_I_3:%.*]] = load i32, i32* [[ADDR1I_1]], ptr_provenance i32* [[TMP15]], align 4, !noalias !18 +; CHECK-NEXT: store i32 [[X_I_3]], i32* [[ADDR2I_1]], ptr_provenance i32* [[TMP13]], align 4, !noalias !18 ; CHECK-NEXT: ret void ; start: Index: llvm/test/Transforms/PropagateAndConvertNoAlias/atomic.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/atomic.ll @@ -0,0 +1,153 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -convert-noalias -S %s | FileCheck %s +; ModuleID = 'test3.c' +source_filename = "test3.c" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%"struct.std::atomic" = type { %"struct.std::__atomic_base" } +%"struct.std::__atomic_base" = type { i32* } + +; Function Attrs: mustprogress nofree nounwind uwtable willreturn +define dso_local void @_Z6test01PiPS_PSt6atomicIS_E(i32* noalias %_p, i32** noalias nocapture %_pp, %"struct.std::atomic"* noalias nocapture %app) local_unnamed_addr #0 personality i32 (...)* @__gxx_personality_v0 { +; CHECK-LABEL: @_Z6test01PiPS_PSt6atomicIS_E( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata [[META3:![0-9]+]]) +; CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i64(i32*** null, i64 0, metadata [[META6:![0-9]+]]) +; CHECK-NEXT: [[T2:%.*]] = call i8* @"llvm.noalias.decl.p0i8.p0p0s_struct.std::atomics.i64"(%"struct.std::atomic"** null, i64 0, metadata [[META8:![0-9]+]]) +; CHECK-NEXT: [[TMP0:%.*]] = call %"struct.std::atomic"* @"llvm.provenance.noalias.p0s_struct.std::atomics.p0i8.p0p0s_struct.std::atomics.p0p0s_struct.std::atomics.i64"(%"struct.std::atomic"* [[APP:%.*]], i8* [[T2]], %"struct.std::atomic"** null, %"struct.std::atomic"** undef, i64 0, metadata [[META8]]), !tbaa [[TBAA10:![0-9]+]], !noalias !14 +; CHECK-NEXT: [[TMP1:%.*]] = bitcast %"struct.std::atomic"* [[TMP0]] to i64* +; CHECK-NEXT: [[T4:%.*]] = bitcast %"struct.std::atomic"* [[APP]] to i64* +; CHECK-NEXT: [[T5:%.*]] = load atomic i64, i64* [[T4]] seq_cst, ptr_provenance i64* [[TMP1]], align 8, !noalias !14 +; CHECK-NEXT: [[TMP2:%.*]] = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* [[_P:%.*]], i8* [[T0]], i32** null, i32** undef, i64 0, metadata [[META3]]), !tbaa [[TBAA10]], !noalias !14 +; CHECK-NEXT: [[T6_GUARD:%.*]] = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* [[_P]], i32* [[TMP2]]) +; CHECK-NEXT: [[T7:%.*]] = bitcast %"struct.std::atomic"* [[APP]] to i64* +; CHECK-NEXT: [[T8:%.*]] = ptrtoint i32* [[T6_GUARD]] to i64 +; CHECK-NEXT: store atomic i64 [[T8]], i64* [[T7]] seq_cst, ptr_provenance i64* [[TMP1]], align 8, !noalias !14 +; CHECK-NEXT: [[T9:%.*]] = bitcast %"struct.std::atomic"* [[APP]] to i64* +; CHECK-NEXT: [[T9_GUARD:%.*]] = call i64* @llvm.noalias.arg.guard.p0i64.p0i64(i64* [[T9]], i64* [[TMP1]]) +; CHECK-NEXT: [[T10:%.*]] = ptrtoint i32* [[T6_GUARD]] to i64 +; CHECK-NEXT: [[T11:%.*]] = atomicrmw xchg i64* [[T9_GUARD]], i64 [[T10]] seq_cst, align 8, !noalias !14 +; CHECK-NEXT: [[TMP3:%.*]] = call i32** @llvm.provenance.noalias.p0p0i32.p0i8.p0p0p0i32.p0p0p0i32.i64(i32** [[_PP:%.*]], i8* [[T1]], i32*** null, i32*** undef, i64 0, metadata [[META6]]), !tbaa [[TBAA10]], !noalias !14 +; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32** [[TMP3]] to i64* +; CHECK-NEXT: [[_M_B_I:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[APP]], i64 0, i32 0 +; CHECK-NEXT: [[T13:%.*]] = bitcast %"struct.std::__atomic_base"* [[_M_B_I]] to i64* +; CHECK-NEXT: [[T13_GUARD:%.*]] = call i64* @llvm.noalias.arg.guard.p0i64.p0i64(i64* [[T13]], i64* [[TMP1]]) +; CHECK-NEXT: [[T14:%.*]] = bitcast i32** [[_PP]] to i64* +; CHECK-NEXT: [[T15:%.*]] = load i64, i64* [[T14]], ptr_provenance i64* [[TMP4]], align 8, !noalias !14 +; CHECK-NEXT: [[T16:%.*]] = ptrtoint i32* [[T6_GUARD]] to i64 +; CHECK-NEXT: [[T17:%.*]] = cmpxchg i64* [[T13_GUARD]], i64 [[T15]], i64 [[T16]] release monotonic, align 8, !noalias !14 +; CHECK-NEXT: [[T18:%.*]] = extractvalue { i64, i1 } [[T17]], 1 +; CHECK-NEXT: br i1 [[T18]], label [[_ZNST13__ATOMIC_BASEIPIE23COMPARE_EXCHANGE_STRONGERS0_S0_ST12MEMORY_ORDERS3__EXIT:%.*]], label [[CMPXCHG_STORE_EXPECTED27_I:%.*]] +; CHECK: cmpxchg.store_expected27.i: +; CHECK-NEXT: [[T19:%.*]] = extractvalue { i64, i1 } [[T17]], 0 +; CHECK-NEXT: store i64 [[T19]], i64* [[T14]], ptr_provenance i64* [[TMP4]], align 8, !noalias !14 +; CHECK-NEXT: br label [[_ZNST13__ATOMIC_BASEIPIE23COMPARE_EXCHANGE_STRONGERS0_S0_ST12MEMORY_ORDERS3__EXIT]] +; CHECK: _ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit: +; CHECK-NEXT: [[_M_B_I23:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[APP]], i64 0, i32 0 +; CHECK-NEXT: [[T20:%.*]] = bitcast %"struct.std::__atomic_base"* [[_M_B_I23]] to i64* +; CHECK-NEXT: [[T20_GUARD:%.*]] = call i64* @llvm.noalias.arg.guard.p0i64.p0i64(i64* [[T20]], i64* [[TMP1]]) +; CHECK-NEXT: [[T21:%.*]] = bitcast i32** [[_PP]] to i64* +; CHECK-NEXT: [[T22:%.*]] = load i64, i64* [[T21]], ptr_provenance i64* [[TMP4]], align 8, !noalias !14 +; CHECK-NEXT: [[T23:%.*]] = ptrtoint i32* [[T6_GUARD]] to i64 +; CHECK-NEXT: [[T24:%.*]] = cmpxchg i64* [[T20_GUARD]], i64 [[T22]], i64 [[T23]] release monotonic, align 8, !noalias !14 +; CHECK-NEXT: [[T25:%.*]] = extractvalue { i64, i1 } [[T24]], 1 +; CHECK-NEXT: br i1 [[T25]], label [[_ZNST13__ATOMIC_BASEIPIE23COMPARE_EXCHANGE_STRONGERS0_S0_ST12MEMORY_ORDERS3__EXIT27:%.*]], label [[CMPXCHG_STORE_EXPECTED27_I26:%.*]] +; CHECK: cmpxchg.store_expected27.i26: +; CHECK-NEXT: [[T26:%.*]] = extractvalue { i64, i1 } [[T24]], 0 +; CHECK-NEXT: store i64 [[T26]], i64* [[T21]], ptr_provenance i64* [[TMP4]], align 8, !noalias !14 +; CHECK-NEXT: br label [[_ZNST13__ATOMIC_BASEIPIE23COMPARE_EXCHANGE_STRONGERS0_S0_ST12MEMORY_ORDERS3__EXIT27]] +; CHECK: _ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit27: +; CHECK-NEXT: ret void +; +entry: + %t0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !3) + %t1 = call i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i64(i32*** null, i64 0, metadata !6) + %t2 = call i8* @"llvm.noalias.decl.p0i8.p0p0s_struct.std::atomics.i64"(%"struct.std::atomic"** null, i64 0, metadata !8) + %t3 = call %"struct.std::atomic"* @"llvm.noalias.p0s_struct.std::atomics.p0i8.p0p0s_struct.std::atomics.i64"(%"struct.std::atomic"* %app, i8* %t2, %"struct.std::atomic"** null, i64 0, metadata !8), !tbaa !10, !noalias !14 + %t4 = bitcast %"struct.std::atomic"* %t3 to i64* + %t5 = load atomic i64, i64* %t4 seq_cst, align 8, !noalias !14 + %t6 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %_p, i8* %t0, i32** null, i64 0, metadata !3), !tbaa !10, !noalias !14 + %t7 = bitcast %"struct.std::atomic"* %t3 to i64* + %t8 = ptrtoint i32* %t6 to i64 + store atomic i64 %t8, i64* %t7 seq_cst, align 8, !noalias !14 + %t9 = bitcast %"struct.std::atomic"* %t3 to i64* + %t10 = ptrtoint i32* %t6 to i64 + %t11 = atomicrmw xchg i64* %t9, i64 %t10 seq_cst, align 8, !noalias !14 + %t12 = call i32** @llvm.noalias.p0p0i32.p0i8.p0p0p0i32.p0p0p0i32.i64(i32** %_pp, i8* %t1, i32*** null, i64 0, metadata !6), !tbaa !10, !noalias !14 + %_M_b.i = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %t3, i64 0, i32 0 + %t13 = bitcast %"struct.std::__atomic_base"* %_M_b.i to i64* + %t14 = bitcast i32** %t12 to i64* + %t15 = load i64, i64* %t14, align 8, !noalias !14 + %t16 = ptrtoint i32* %t6 to i64 + %t17 = cmpxchg i64* %t13, i64 %t15, i64 %t16 release monotonic, align 8, !noalias !14 + %t18 = extractvalue { i64, i1 } %t17, 1 + br i1 %t18, label %_ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit, label %cmpxchg.store_expected27.i + +cmpxchg.store_expected27.i: ; preds = %entry + %t19 = extractvalue { i64, i1 } %t17, 0 + store i64 %t19, i64* %t14, align 8, !noalias !14 + br label %_ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit + +_ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit: ; preds = %entry, %cmpxchg.store_expected27.i + %_M_b.i23 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %t3, i64 0, i32 0 + %t20 = bitcast %"struct.std::__atomic_base"* %_M_b.i23 to i64* + %t21 = bitcast i32** %t12 to i64* + %t22 = load i64, i64* %t21, align 8, !noalias !14 + %t23 = ptrtoint i32* %t6 to i64 + %t24 = cmpxchg i64* %t20, i64 %t22, i64 %t23 release monotonic, align 8, !noalias !14 + %t25 = extractvalue { i64, i1 } %t24, 1 + br i1 %t25, label %_ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit27, label %cmpxchg.store_expected27.i26 + +cmpxchg.store_expected27.i26: ; preds = %_ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit + %t26 = extractvalue { i64, i1 } %t24, 0 + store i64 %t26, i64* %t21, align 8, !noalias !14 + br label %_ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit27 + +_ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit27: ; preds = %_ZNSt13__atomic_baseIPiE23compare_exchange_strongERS0_S0_St12memory_orderS3_.exit, %cmpxchg.store_expected27.i26 + ret void +} + +; Function Attrs: inaccessiblememonly mustprogress nofree nosync nounwind willreturn +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32**, i64, metadata) #1 + +; Function Attrs: inaccessiblememonly mustprogress nofree nosync nounwind willreturn +declare i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i64(i32***, i64, metadata) #1 + +; Function Attrs: inaccessiblememonly mustprogress nofree nosync nounwind willreturn +declare i8* @"llvm.noalias.decl.p0i8.p0p0s_struct.std::atomics.i64"(%"struct.std::atomic"**, i64, metadata) #1 + +; Function Attrs: argmemonly nofree nosync nounwind speculatable willreturn +declare %"struct.std::atomic"* @"llvm.noalias.p0s_struct.std::atomics.p0i8.p0p0s_struct.std::atomics.i64"(%"struct.std::atomic"*, i8*, %"struct.std::atomic"**, i64, metadata) #3 + +; Function Attrs: argmemonly nofree nosync nounwind speculatable willreturn +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32*, i8*, i32**, i64, metadata) #3 + +; Function Attrs: argmemonly nofree nosync nounwind speculatable willreturn +declare i32** @llvm.noalias.p0p0i32.p0i8.p0p0p0i32.p0p0p0i32.i64(i32**, i8*, i32***, i64, metadata) #3 + +declare dso_local i32 @__gxx_personality_v0(...) + +attributes #0 = { mustprogress nofree nounwind uwtable willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { inaccessiblememonly mustprogress nofree nosync nounwind willreturn } +attributes #2 = { mustprogress nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #3 = { argmemonly nofree nosync nounwind speculatable willreturn } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"uwtable", i32 1} +!2 = !{!"clang"} +!3 = !{!4} +!4 = distinct !{!4, !5, !"_Z6test01PiPS_PSt6atomicIS_E: _p"} +!5 = distinct !{!5, !"_Z6test01PiPS_PSt6atomicIS_E"} +!6 = !{!7} +!7 = distinct !{!7, !5, !"_Z6test01PiPS_PSt6atomicIS_E: _pp"} +!8 = !{!9} +!9 = distinct !{!9, !5, !"_Z6test01PiPS_PSt6atomicIS_E: app"} +!10 = !{!11, !11, i64 0} +!11 = !{!"any pointer", !12, i64 0} +!12 = !{!"omnipotent char", !13, i64 0} +!13 = !{!"Simple C++ TBAA"} +!14 = !{!4, !7, !9} Index: llvm/test/Transforms/PropagateAndConvertNoAlias/basictest.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/basictest.ll @@ -0,0 +1,80 @@ +; RUN: opt < %s -convert-noalias -verify -S | FileCheck %s +; RUN: opt < %s -passes=convert-noalias,verify -S | FileCheck %s + +@gpA = common dso_local global i32* null, align 4 + +; Function Attrs: nounwind +define dso_local void @test01(i32* %_pA) #0 { +entry: + %pA.decl = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %pA = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %pA.decl, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 + %arrayidx = getelementptr inbounds i32, i32* %pA, i32 10 + store i32 42, i32* %arrayidx, align 4, !tbaa !9, !noalias !2 + %pA.2 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %pA.decl, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 + %add.ptr = getelementptr inbounds i32, i32* %pA.2, i32 1 + %pA.3 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %add.ptr, i8* %pA.decl, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 + %arrayidx1 = getelementptr inbounds i32, i32* %pA.3, i32 11 + store i32 43, i32* %arrayidx1, align 4, !tbaa !9, !noalias !2 + ret void +} + +; CHECK-LABEL: @test01( +; CHECK-NEXT: entry: +; CHECK-NEXT: %pA.decl = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) +; CHECK-NEXT: %0 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %pA.decl, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 +; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, i32* %_pA, i32 10 +; CHECK-NEXT: store i32 42, i32* %arrayidx, ptr_provenance i32* %0, align 4, !tbaa !9, !noalias !2 +; CHECK-NEXT: %add.ptr = getelementptr inbounds i32, i32* %_pA, i32 1 +; CHECK-NEXT: %arrayidx1 = getelementptr inbounds i32, i32* %add.ptr, i32 11 +; CHECK-NEXT: store i32 43, i32* %arrayidx1, ptr_provenance i32* %0, align 4, !tbaa !9, !noalias !2 +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; Function Attrs: nounwind +define dso_local i32* @test02(i32* %_pA) #0 { +entry: + %pA.decl = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) + %pA.1 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %pA.decl, i32** null, i32 0, metadata !11), !tbaa !5, !noalias !11 + store i32* %pA.1, i32** @gpA, align 4, !tbaa !5, !noalias !11 + %pA.2 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %pA.decl, i32** null, i32 0, metadata !11), !tbaa !5, !noalias !11 + ret i32* %pA.2 +} + +; CHECK-LABEL: @test02( +; CHECK-NEXT: entry: +; CHECK-NEXT: %pA.decl = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) +; CHECK-NEXT: %0 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %pA.decl, i32** null, i32** undef, i32 0, metadata !11), !tbaa !5, !noalias !11 +; CHECK-NEXT: %pA.1.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %0) +; CHECK-NEXT: store i32* %pA.1.guard, i32** @gpA, align 4, !tbaa !5, !noalias !11 +; CHECK-NEXT: %pA.2.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %0) +; CHECK-NEXT: ret i32* %pA.2.guard +; CHECK-NEXT: } + + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { argmemonly nounwind speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test01: pA"} +!4 = distinct !{!4, !"test01"} +!5 = !{!6, !6, i64 0, i64 4} +!6 = !{!7, i64 4, !"any pointer"} +!7 = !{!8, i64 1, !"omnipotent char"} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!7, i64 4, !"int"} +!11 = !{!12} +!12 = distinct !{!12, !13, !"test02: pA"} +!13 = distinct !{!13, !"test02"} Index: llvm/test/Transforms/PropagateAndConvertNoAlias/call.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/call.ll @@ -0,0 +1,112 @@ +; RUN: opt < %s -convert-noalias -verify -S | FileCheck %s +; RUN: opt < %s -passes=convert-noalias,verify -S | FileCheck %s + +target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" + +; Function Attrs: nounwind +define dso_local i32* @passP(i32* %_pA) #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %1 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 42, i32* %1, align 4, !tbaa !9, !noalias !2 + %2 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !2), !tbaa !5, !noalias !2 + ret i32* %2 +} + +; CHECK-LABEL: @passP( +; CHECK-NEXT: entry: +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) +; CHECK-NEXT: %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 +; CHECK-NEXT: store i32 42, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 +; CHECK-NEXT: %.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %1) +; CHECK-NEXT: ret i32* %.guard +; CHECK-NEXT: } + +; Function Attrs: nounwind +define dso_local void @test01(i32* %_pA) #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) + %1 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !11), !tbaa !5, !noalias !11 + store i32 41, i32* %1, align 4, !tbaa !9, !noalias !11 + %2 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !11), !tbaa !5, !noalias !11 + %call = call i32* @passP(i32* %2), !noalias !11 + store i32 43, i32* %call, align 4, !tbaa !9, !noalias !11 + ret void +} + +; CHECK-LABEL: @test01( +; CHECK-NEXT: entry: +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) +; CHECK-NEXT: %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !11), !tbaa !5, !noalias !11 +; CHECK-NEXT: store i32 41, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !11 +; CHECK-NEXT: %.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %1) +; CHECK-NEXT: %call = call i32* @passP(i32* %.guard), !noalias !11 +; CHECK-NEXT: store i32 43, i32* %call, align 4, !tbaa !9, !noalias !11 +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; Function Attrs: nounwind +define dso_local void @test02(i32* %_pA) #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) + %1 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !11), !tbaa !5, !noalias !11 + store i32 41, i32* %1, align 4, !tbaa !9, !noalias !11 + %2 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !11), !tbaa !5, !noalias !11 + br label %block + +block: + %tmp0 = phi i32* [ %2, %entry ] + %tmp1 = phi i32* [ %1, %entry ] + %call = call i32* @passP(i32* %tmp0), !noalias !11 + store i32 43, i32* %call, align 4, !tbaa !9, !noalias !11 + ret void +} + + +; CHECK-LABEL: @test02( +; CHECK-NEXT: entry: +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) +; CHECK-NEXT: %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !11), !tbaa !5, !noalias !11 +; CHECK-NEXT: store i32 41, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !11 +; CHECK-NEXT: br label %block +; CHECK: block: +; CHECK-NEXT: %prov.tmp0 = phi i32* [ %1, %entry ] +; CHECK-NEXT: %tmp0 = phi i32* [ %_pA, %entry ] +; CHECK-NEXT: %prov.tmp1 = phi i32* [ %1, %entry ] +; CHECK-NEXT: %tmp1 = phi i32* [ %_pA, %entry ] +; CHECK-NEXT: %tmp0.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %tmp0, i32* %prov.tmp0) +; CHECK-NEXT: %call = call i32* @passP(i32* %tmp0.guard), !noalias !11 +; CHECK-NEXT: store i32 43, i32* %call, align 4, !tbaa !9, !noalias !11 +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #2 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { argmemonly nounwind } +attributes #3 = { argmemonly nounwind speculatable } +attributes #4 = { nounwind readnone speculatable } +attributes #5 = { nounwind readnone } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"passP: pA"} +!4 = distinct !{!4, !"passP"} +!5 = !{!6, !6, i64 0, i64 4} +!6 = !{!7, i64 4, !"any pointer"} +!7 = !{!8, i64 1, !"omnipotent char"} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!7, i64 4, !"int"} +!11 = !{!12} +!12 = distinct !{!12, !13, !"test01: p1"} +!13 = distinct !{!13, !"test01"} Index: llvm/test/Transforms/PropagateAndConvertNoAlias/degenerated.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/degenerated.ll @@ -0,0 +1,126 @@ +; RUN: opt < %s -convert-noalias -verify -S | FileCheck %s +; RUN: opt < %s -passes=convert-noalias,verify -S | FileCheck %s + +target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" + +; Function Attrs: nounwind +define dso_local void @test01(i32* %_pA) local_unnamed_addr #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 41, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + %.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %1) + %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) #5, !noalias !2 + %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %.guard, i8* %2, i32** null, i32** undef, i32 0, metadata !11) #3, !tbaa !5, !noalias !14 + store i32 42, i32* %.guard, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !14 + %.guard.guard.guard.guard.i = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %.guard, i32* %3) #1 + store i32 43, i32* %.guard.guard.guard.guard.i, ptr_provenance i32* undef, align 4, !tbaa !9, !noalias !2 + ret void +} + +; CHECK-LABEL: @test01( +; CHECK-NEXT: entry: +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) +; CHECK-NEXT: %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 +; CHECK-NEXT: store i32 41, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 +; CHECK-NEXT: %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) #{{[0-9]+}}, !noalias !2 +; CHECK-NEXT: %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %1, i8* %2, i32** null, i32** undef, i32 0, metadata !11) #{{[0-9]+}}, !tbaa !5, !noalias !14 +; CHECK-NEXT: store i32 42, i32* %_pA, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !14 +; CHECK-NEXT: store i32 43, i32* %_pA, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !2 +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; Function Attrs: nounwind +define dso_local void @test02(i32* %_pA) local_unnamed_addr #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 41, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + %.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %1) + %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) #5, !noalias !2 + %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %.guard, i8* %2, i32** null, i32** undef, i32 0, metadata !11) #3, !tbaa !5, !noalias !14 + store i32 42, i32* %.guard, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !14 + %deg01 = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %.guard, i32* %.guard) #1 + %deg02 = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %.guard, i32* undef) #1 + call void @foo(i32* %deg01), !noalias !14 + call void @foo(i32* %deg01), !noalias !14 + ret void +} + +; CHECK-LABEL: @test02( +; CHECK: ret void + +%class.e = type { %class.a } +%class.a = type { i32 } + +@g = global %class.e zeroinitializer, align 4 + +; Function Attrs: nounwind +define internal fastcc void @test03() unnamed_addr #0 { +entry: + %0 = tail call i8* @llvm.noalias.decl.p0i8.p0p0s_class.es.i64(%class.e** null, i64 0, metadata !15) + %1 = tail call %class.e* @llvm.provenance.noalias.p0s_class.es.p0i8.p0p0s_class.es.p0p0s_class.es.i64(%class.e* nonnull @g, i8* %0, %class.e** null, %class.e** undef, i64 0, metadata !15) + %2 = getelementptr inbounds %class.e, %class.e* %1, i32 0, i32 0 + %.guard.guard = tail call %class.a* @llvm.noalias.arg.guard.p0s_class.as.p0s_class.as(%class.a* getelementptr inbounds (%class.e, %class.e* @g, i32 0, i32 0), %class.a* %2) + call void @foobar03(%class.a* %.guard.guard, i32 5), !noalias !15 + ret void +} + +; CHECK-LABEL: @test03( +; CHECK: call %class.a* @llvm.noalias.arg.guard.p0s_class.as.p0s_class.as +; CHECK: ret void + +; Function Attrs: nounwind +declare void @foobar03(%class.a*, i32) local_unnamed_addr #0 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) #2 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #3 + +; Function Attrs: nounwind readnone +declare i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32*, i32*) #4 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0s_class.es.i64(%class.e**, i64, metadata) #1 + +; Function Attrs: nounwind readnone speculatable +declare %class.e* @llvm.provenance.noalias.p0s_class.es.p0i8.p0p0s_class.es.p0p0s_class.es.i64(%class.e*, i8*, %class.e**, %class.e**, i64, metadata) #3 + +; Function Attrs: nounwind readnone +declare %class.a* @llvm.noalias.arg.guard.p0s_class.as.p0s_class.as(%class.a*, %class.a*) #4 + +declare void @foo(i32*) + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { argmemonly nounwind speculatable } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind readnone } +attributes #5 = { nounwind } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test01: p1"} +!4 = distinct !{!4, !"test01"} +!5 = !{!6, !6, i64 0, i64 4} +!6 = !{!7, i64 4, !"any pointer"} +!7 = !{!8, i64 1, !"omnipotent char"} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!7, i64 4, !"int"} +!11 = !{!12} +!12 = distinct !{!12, !13, !"passP: pA"} +!13 = distinct !{!13, !"passP"} +!14 = !{!12, !3} +!15 = !{!16} +!16 = distinct !{!16, !17, !"test03: %agg.result"} +!17 = distinct !{!17, !"test03"} Index: llvm/test/Transforms/PropagateAndConvertNoAlias/double_noalias.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/double_noalias.ll @@ -0,0 +1,69 @@ +; RUN: opt < %s -convert-noalias -verify -S | FileCheck %s +; RUN: opt < %s -passes=convert-noalias,verify -S | FileCheck %s + +target datalayout = "e-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f16:16:16-f32:32:32-f64:32:32-p:32:32:32:32:8-s0:32:32-a0:0:32-S32-n16:32-v128:32:32-P0-p0:32:32:32:32:8" + +; Function Attrs: nounwind +define dso_local void @test_rr(i32** %_p) #0 !noalias !2 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i32(i32*** null, i32 0, metadata !5) + %1 = call i32** @llvm.noalias.p0p0i32.p0i8.p0p0p0i32.i32(i32** %_p, i8* %0, i32*** null, i32 0, metadata !5), !tbaa !7, !noalias !11 + %arrayidx = getelementptr inbounds i32*, i32** %1, i32 1 + %2 = load i32*, i32** %arrayidx, align 4, !tbaa !7, !noalias !11 + %3 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %2, i8* null, i32** %arrayidx, i32 0, metadata !2), !tbaa !7, !noalias !11 + %arrayidx1 = getelementptr inbounds i32, i32* %3, i32 2 + %4 = load i32, i32* %arrayidx1, align 4, !tbaa !12, !noalias !11 + %add = add nsw i32 %4, 1 + %5 = call i32** @llvm.noalias.p0p0i32.p0i8.p0p0p0i32.i32(i32** %_p, i8* %0, i32*** null, i32 0, metadata !5), !tbaa !7, !noalias !11 + %6 = load i32*, i32** %5, align 4, !tbaa !7, !noalias !11 + %7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %6, i8* null, i32** %5, i32 0, metadata !2), !tbaa !7, !noalias !11 + store i32 %add, i32* %7, align 4, !tbaa !12, !noalias !11 + ret void +} + +; CHECK-LABEL: @test_rr( +; CHECK-NEXT: entry: +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i32(i32*** null, i32 0, metadata !5) +; CHECK-NEXT: %1 = call i32** @llvm.provenance.noalias.p0p0i32.p0i8.p0p0p0i32.p0p0p0i32.i32(i32** %_p, i8* %0, i32*** null, i32*** undef, i32 0, metadata !5), !tbaa !7, !noalias !11 +; CHECK-NEXT: %arrayidx = getelementptr inbounds i32*, i32** %_p, i32 1 +; CHECK-NEXT: %2 = load i32*, i32** %arrayidx, ptr_provenance i32** %1, align 4, !tbaa !7, !noalias !11 +; CHECK-NEXT: %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %2, i8* null, i32** %arrayidx, i32** %1, i32 0, metadata !2), !tbaa !7, !noalias !11 +; CHECK-NEXT: %arrayidx1 = getelementptr inbounds i32, i32* %2, i32 2 +; CHECK-NEXT: %4 = load i32, i32* %arrayidx1, ptr_provenance i32* %3, align 4, !tbaa !12, !noalias !11 +; CHECK-NEXT: %add = add nsw i32 %4, 1 +; CHECK-NEXT: %5 = load i32*, i32** %_p, ptr_provenance i32** %1, align 4, !tbaa !7, !noalias !11 +; CHECK-NEXT: %6 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %5, i8* null, i32** %_p, i32** %1, i32 0, metadata !2), !tbaa !7, !noalias !11 +; CHECK-NEXT: store i32 %add, i32* %5, ptr_provenance i32* %6, align 4, !tbaa !12, !noalias !11 +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) #1 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0p0i32.i32(i32***, i32, metadata) #2 + +; Function Attrs: argmemonly nounwind speculatable +declare i32** @llvm.noalias.p0p0i32.p0i8.p0p0p0i32.i32(i32**, i8*, i32***, i32, metadata) #1 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind speculatable } +attributes #2 = { argmemonly nounwind } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test_rr: unknown scope"} +!4 = distinct !{!4, !"test_rr"} +!5 = !{!6} +!6 = distinct !{!6, !4, !"test_rr: rprp"} +!7 = !{!8, !8, i64 0, i64 4} +!8 = !{!9, i64 4, !"any pointer"} +!9 = !{!10, i64 1, !"omnipotent char"} +!10 = !{!"Simple C/C++ TBAA"} +!11 = !{!6, !3} +!12 = !{!13, !13, i64 0, i64 4} +!13 = !{!9, i64 4, !"int"} Index: llvm/test/Transforms/PropagateAndConvertNoAlias/inlined.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/inlined.ll @@ -0,0 +1,69 @@ +; RUN: opt < %s -convert-noalias -verify -S | FileCheck %s +; RUN: opt < %s -passes=convert-noalias,verify -S | FileCheck %s + +target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" + +; Function Attrs: nounwind +define dso_local void @test01(i32* %_pA) local_unnamed_addr #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + store i32 41, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 + %.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %1) + %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) #5, !noalias !2 + %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %.guard, i8* %2, i32** null, i32** undef, i32 0, metadata !11) #3, !tbaa !5, !noalias !14 + store i32 42, i32* %.guard, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !14 + %.guard.guard.guard.guard.i = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %.guard, i32* %3) #1 + store i32 43, i32* %.guard.guard.guard.guard.i, ptr_provenance i32* undef, align 4, !tbaa !9, !noalias !2 + ret void +} + +; CHECK-LABEL: @test01( +; CHECK-NEXT: entry: +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) +; CHECK-NEXT: %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 +; CHECK-NEXT: store i32 41, i32* %_pA, ptr_provenance i32* %1, align 4, !tbaa !9, !noalias !2 +; CHECK-NEXT: %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !11) #{{[0-9]+}}, !noalias !2 +; CHECK-NEXT: %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %1, i8* %2, i32** null, i32** undef, i32 0, metadata !11) #{{[0-9]+}}, !tbaa !5, !noalias !14 +; CHECK-NEXT: store i32 42, i32* %_pA, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !14 +; CHECK-NEXT: store i32 43, i32* %_pA, ptr_provenance i32* %3, align 4, !tbaa !9, !noalias !2 +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) #2 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #3 + +; Function Attrs: nounwind readnone +declare i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32*, i32*) #4 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { argmemonly nounwind speculatable } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind readnone } +attributes #5 = { nounwind } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test01: p1"} +!4 = distinct !{!4, !"test01"} +!5 = !{!6, !6, i64 0, i64 4} +!6 = !{!7, i64 4, !"any pointer"} +!7 = !{!8, i64 1, !"omnipotent char"} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!7, i64 4, !"int"} +!11 = !{!12} +!12 = distinct !{!12, !13, !"passP: pA"} +!13 = distinct !{!13, !"passP"} +!14 = !{!12, !3} Index: llvm/test/Transforms/PropagateAndConvertNoAlias/noalias_cleanup.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/noalias_cleanup.ll @@ -0,0 +1,47 @@ +; RUN: opt < %s -convert-noalias -verify -S | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define dso_local void @foo() local_unnamed_addr #0 { +entry: + br label %for.cond + +for.cond: ; preds = %if.then, %entry + %prov.bar.0 = phi i32* [ undef, %entry ], [ %prov.bar.0, %if.then ] + br i1 undef, label %for.cond3thread-pre-split, label %if.then + +if.then: ; preds = %for.cond + %0 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %prov.bar.0, i8* undef, i32** null, i32** undef, i64 0, metadata !1) + br i1 undef, label %for.cond, label %for.body + +for.body: ; preds = %for.body, %if.then + %prov.bar.116 = phi i32* [ %1, %for.body ], [ %prov.bar.0, %if.then ] + %1 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %prov.bar.116, i8* undef, i32** null, i32** undef, i64 0, metadata !1) + br label %for.body + +for.cond3thread-pre-split: ; preds = %for.cond + br label %for.body5 + +for.body5: ; preds = %for.body5, %for.cond3thread-pre-split + %prov.bar.220 = phi i32* [ %2, %for.body5 ], [ %prov.bar.0, %for.cond3thread-pre-split ] + %2 = tail call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %prov.bar.220, i8* undef, i32** null, i32** undef, i64 0, metadata !1) + br label %for.body5 +} + +; CHECK-LABEL: @foo +; CHECK: call i32* @llvm.provenance.noalias +; CHECK-NOT: call i32* @llvm.provenance.noalias + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32*, i8*, i32**, i32**, i64, metadata) #1 + +attributes #0 = { "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.ident = !{!0} + +!0 = !{!"clang)"} +!1 = !{!2} +!2 = distinct !{!2, !3, !"foo: bar"} +!3 = distinct !{!3, !"foo"} Index: llvm/test/Transforms/PropagateAndConvertNoAlias/reduced01.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/reduced01.ll @@ -0,0 +1,76 @@ +; RUN: opt < %s -convert-noalias -verify -S | FileCheck %s +; RUN: opt < %s -passes=convert-noalias,verify -S | FileCheck %s +; RUN: opt < %s -convert-noalias -verify -convert-noalias -verify -S | FileCheck %s + +target datalayout = "e-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f16:16:16-f32:32:32-f64:32:32-p:32:32:32:32:8-s0:32:32-a0:0:32-S32-n16:32-v128:32:32-P0-p0:32:32:32:32:8" + +%struct.a = type { i8 } + +; Function Attrs: noreturn +define dso_local void @_Z3fooPii(i32* %_f, i32 %g) local_unnamed_addr #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_f, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 + %2 = bitcast i32* %1 to %struct.a* + %3 = bitcast i32* %_f to %struct.a* + br label %for.cond + +for.cond: ; preds = %for.cond, %entry + %prov.h.0 = phi %struct.a* [ %2, %entry ], [ %h.0.guard, %for.cond ] + %h.0 = phi %struct.a* [ %3, %entry ], [ %h.0.guard, %for.cond ] + %h.0.guard = call %struct.a* @llvm.noalias.arg.guard.p0s_struct.as.p0s_struct.as(%struct.a* %h.0, %struct.a* %prov.h.0) + %4 = getelementptr inbounds %struct.a, %struct.a* %h.0, i32 0, i32 0 + %prov.h.1 = bitcast %struct.a* %prov.h.0 to i8* + %.unpack = load i8, i8* %4, ptr_provenance i8* %prov.h.1, align 1, !noalias !2 + %5 = insertvalue %struct.a undef, i8 %.unpack, 0 + %call = call i32 @_Z1b1a(%struct.a %5), !noalias !2 + br label %for.cond +} +; CHECK: define dso_local void @_Z3fooPii(i32* %_f, i32 %g) local_unnamed_addr #0 { +; CHECK-NEXT: entry: +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) +; CHECK-NEXT: %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_f, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !5, !noalias !2 +; CHECK-NEXT: %2 = bitcast i32* %1 to %struct.a* +; CHECK-NEXT: %3 = bitcast i32* %_f to %struct.a* +; CHECK-NEXT: br label %for.cond +; CHECK: for.cond: ; preds = %for.cond, %entry +; CHECK-NEXT: %prov.h.0 = phi %struct.a* [ %2, %entry ], [ %prov.h.0, %for.cond ] +; CHECK-NEXT: %prov.h.01 = phi %struct.a* [ %3, %entry ], [ %prov.h.0, %for.cond ] +; CHECK-NEXT: %h.0 = phi %struct.a* [ %3, %entry ], [ %h.0, %for.cond ] +; CHECK-NEXT: %4 = getelementptr inbounds %struct.a, %struct.a* %h.0, i32 0, i32 0 +; CHECK-NEXT: %prov.h.1 = bitcast %struct.a* %prov.h.0 to i8* +; CHECK-NEXT: %.unpack = load i8, i8* %4, ptr_provenance i8* %prov.h.1, align 1, !noalias !2 +; CHECK-NEXT: %5 = insertvalue %struct.a undef, i8 %.unpack, 0 +; CHECK-NEXT: %call = call i32 @_Z1b1a(%struct.a %5), !noalias !2 +; CHECK-NEXT: br label %for.cond + + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +declare dso_local i32 @_Z1b1a(%struct.a) local_unnamed_addr #2 + +; Function Attrs: nounwind readnone +declare %struct.a* @llvm.noalias.arg.guard.p0s_struct.as.p0s_struct.as(%struct.a*, %struct.a*) #3 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32*, i8*, i32**, i32**, i32, metadata) #4 + +attributes #0 = { noreturn "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind readnone } +attributes #4 = { nounwind readnone speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 7.0.0 "} +!2 = !{!3} +!3 = distinct !{!3, !4, !"_Z3fooPii: f"} +!4 = distinct !{!4, !"_Z3fooPii"} +!5 = !{!6, !6, i64 0} +!6 = !{!"any pointer", !7, i64 0} +!7 = !{!"omnipotent char", !8, i64 0} +!8 = !{!"Simple C++ TBAA"} Index: llvm/test/Transforms/PropagateAndConvertNoAlias/select_and_phi.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/select_and_phi.ll @@ -0,0 +1,208 @@ +; RUN: opt < %s -convert-noalias -verify -S | FileCheck %s +; RUN: opt < %s -passes=convert-noalias,verify -S | FileCheck %s +; RUN: opt < %s -convert-noalias -verify -convert-noalias -verify -S | FileCheck %s + +; Function Attrs: nounwind +define dso_local void @test_phi01(i32* %_pA, i32** %_pB, i32 %n) #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) + %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !5) + %arrayidx = getelementptr inbounds i32*, i32** %_pB, i32 2 + %2 = load i32*, i32** %arrayidx, align 4, !tbaa !7, !noalias !11 + %3 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !2), !tbaa !7, !noalias !11 + %4 = load i32*, i32** %_pB, align 4, !tbaa !7, !noalias !11 + %arrayidx2 = getelementptr inbounds i32*, i32** %_pB, i32 1 + %5 = load i32*, i32** %arrayidx2, align 4, !tbaa !7, !noalias !11 + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %pTmp00.0 = phi i32* [ %4, %entry ], [ %pTmp01.0, %for.body ] + %pTmp01.0 = phi i32* [ %5, %entry ], [ %3, %for.body ] + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %cmp = icmp slt i32 %i.0, %n + br i1 %cmp, label %for.body, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.cond + %6 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !2), !tbaa !7, !noalias !11 + store i32 99, i32* %6, align 4, !tbaa !12, !noalias !11 + store i32 42, i32* %pTmp00.0, align 4, !tbaa !12, !noalias !11 + %cmp5 = icmp sgt i32 %n, 5 + %7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %2, i8* %1, i32** null, i32 0, metadata !5) + %cond = select i1 %cmp5, i32* %pTmp00.0, i32* %7 + store i32 43, i32* %cond, align 4, !tbaa !12, !noalias !11 + ret void + +for.body: ; preds = %for.cond + %arrayidx3 = getelementptr inbounds i32, i32* %pTmp01.0, i32 1 + %8 = load i32, i32* %arrayidx3, align 4, !tbaa !12, !noalias !11 + %arrayidx4 = getelementptr inbounds i32, i32* %pTmp00.0, i32 1 + store i32 %8, i32* %arrayidx4, align 4, !tbaa !12, !noalias !11 + %inc = add nsw i32 %i.0, 1 + br label %for.cond +} + +; CHECK-LABEL: @test_phi01( +; CHECK-NEXT: entry: +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !2) +; CHECK-NEXT: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !5) +; CHECK-NEXT: %arrayidx = getelementptr inbounds i32*, i32** %_pB, i32 2 +; CHECK-NEXT: %2 = load i32*, i32** %arrayidx, align 4, !tbaa !7, !noalias !11 +; CHECK-NEXT: %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !2), !tbaa !7, !noalias !11 +; CHECK-NEXT: %4 = load i32*, i32** %_pB, align 4, !tbaa !7, !noalias !11 +; CHECK-NEXT: %arrayidx2 = getelementptr inbounds i32*, i32** %_pB, i32 1 +; CHECK-NEXT: %5 = load i32*, i32** %arrayidx2, align 4, !tbaa !7, !noalias !11 +; CHECK-NEXT: br label %for.cond +; CHECK: for.cond: +; CHECK-NEXT: %prov.pTmp00.0 = phi i32* [ %4, %entry ], [ %prov.pTmp01.0, %for.body ] +; CHECK-NEXT: %pTmp00.0 = phi i32* [ %4, %entry ], [ %pTmp01.0, %for.body ] +; CHECK-NEXT: %prov.pTmp01.0 = phi i32* [ %5, %entry ], [ %3, %for.body ] +; CHECK-NEXT: %pTmp01.0 = phi i32* [ %5, %entry ], [ %_pA, %for.body ] +; CHECK-NEXT: %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] +; CHECK-NEXT: %cmp = icmp slt i32 %i.0, %n +; CHECK-NEXT: br i1 %cmp, label %for.body, label %for.cond.cleanup +; CHECK: for.cond.cleanup: +; CHECK-NEXT: store i32 99, i32* %_pA, ptr_provenance i32* %3, align 4, !tbaa !12, !noalias !11 +; CHECK-NEXT: store i32 42, i32* %pTmp00.0, ptr_provenance i32* %prov.pTmp00.0, align 4, !tbaa !12, !noalias !11 +; CHECK-NEXT: %cmp5 = icmp sgt i32 %n, 5 +; CHECK-NEXT: %6 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %2, i8* %1, i32** null, i32** undef, i32 0, metadata !5) +; CHECK-NEXT: %prov.cond = select i1 %cmp5, i32* %prov.pTmp00.0, i32* %6 +; CHECK-NEXT: %cond = select i1 %cmp5, i32* %pTmp00.0, i32* %2 +; CHECK-NEXT: store i32 43, i32* %cond, ptr_provenance i32* %prov.cond, align 4, !tbaa !12, !noalias !11 +; CHECK-NEXT: ret void +; CHECK: for.body: +; CHECK-NEXT: %arrayidx3 = getelementptr inbounds i32, i32* %pTmp01.0, i32 1 +; CHECK-NEXT: %7 = load i32, i32* %arrayidx3, ptr_provenance i32* %prov.pTmp01.0, align 4, !tbaa !12, !noalias !11 +; CHECK-NEXT: %arrayidx4 = getelementptr inbounds i32, i32* %pTmp00.0, i32 1 +; CHECK-NEXT: store i32 %7, i32* %arrayidx4, ptr_provenance i32* %prov.pTmp00.0, align 4, !tbaa !12, !noalias !11 +; CHECK-NEXT: %inc = add nsw i32 %i.0, 1 +; CHECK-NEXT: br label %for.cond +; CHECK-NEXT: } + + +; Function Attrs: nounwind +define dso_local void @test_phi02(i32* %_pA, i32** %_pB, i32 %n) #0 { +entry: + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !14) + %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !17) + %arrayidx = getelementptr inbounds i32*, i32** %_pB, i32 2 + %2 = load i32*, i32** %arrayidx, align 4, !tbaa !7, !noalias !19 + %3 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !14), !tbaa !7, !noalias !19 + %4 = load i32*, i32** %_pB, align 4, !tbaa !7, !noalias !19 + %arrayidx2 = getelementptr inbounds i32*, i32** %_pB, i32 1 + %5 = load i32*, i32** %arrayidx2, align 4, !tbaa !7, !noalias !19 + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %pTmp00.0 = phi i32* [ %4, %entry ], [ %pTmp01.0, %for.body ] + %pTmp01.0 = phi i32* [ %5, %entry ], [ %3, %for.body ] + %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %cmp = icmp slt i32 %i.0, %n + br i1 %cmp, label %for.body, label %for.cond.cleanup + +for.cond.cleanup: ; preds = %for.cond + %6 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32 0, metadata !14), !tbaa !7, !noalias !19 + %7 = bitcast i32* %6 to i16* + store i16 99, i16* %7, align 2, !tbaa !20, !noalias !19 + %8 = bitcast i32* %pTmp00.0 to i16* + store i16 42, i16* %8, align 2, !tbaa !20, !noalias !19 + %cmp5 = icmp sgt i32 %n, 5 + %9 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %2, i8* %1, i32** null, i32 0, metadata !17) + %cond = select i1 %cmp5, i32* %pTmp00.0, i32* %9 + %10 = bitcast i32* %cond to i16* + store i16 43, i16* %10, align 2, !tbaa !20, !noalias !19 + ret void + +for.body: ; preds = %for.cond + %11 = bitcast i32* %pTmp01.0 to i16* + %arrayidx3 = getelementptr inbounds i16, i16* %11, i32 1 + %12 = load i16, i16* %arrayidx3, align 2, !tbaa !20, !noalias !19 + %13 = bitcast i32* %pTmp00.0 to i16* + %arrayidx4 = getelementptr inbounds i16, i16* %13, i32 1 + store i16 %12, i16* %arrayidx4, align 2, !tbaa !20, !noalias !19 + %inc = add nsw i32 %i.0, 1 + br label %for.cond +} + +; CHECK-LABEL: @test_phi02( +; CHECK-NEXT: entry: +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !14) +; CHECK-NEXT: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !17) +; CHECK-NEXT: %arrayidx = getelementptr inbounds i32*, i32** %_pB, i32 2 +; CHECK-NEXT: %2 = load i32*, i32** %arrayidx, align 4, !tbaa !7, !noalias !19 +; CHECK-NEXT: %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %0, i32** null, i32** undef, i32 0, metadata !14), !tbaa !7, !noalias !19 +; CHECK-NEXT: %4 = load i32*, i32** %_pB, align 4, !tbaa !7, !noalias !19 +; CHECK-NEXT: %arrayidx2 = getelementptr inbounds i32*, i32** %_pB, i32 1 +; CHECK-NEXT: %5 = load i32*, i32** %arrayidx2, align 4, !tbaa !7, !noalias !19 +; CHECK-NEXT: br label %for.cond +; CHECK: for.cond: +; CHECK-NEXT: %prov.pTmp00.0 = phi i32* [ %4, %entry ], [ %prov.pTmp01.0, %for.body ] +; CHECK-NEXT: %pTmp00.0 = phi i32* [ %4, %entry ], [ %pTmp01.0, %for.body ] +; CHECK-NEXT: %prov.pTmp01.0 = phi i32* [ %5, %entry ], [ %3, %for.body ] +; CHECK-NEXT: %pTmp01.0 = phi i32* [ %5, %entry ], [ %_pA, %for.body ] +; CHECK-NEXT: %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ] +; CHECK-NEXT: %6 = bitcast i32* %prov.pTmp00.0 to i16* +; CHECK-NEXT: %7 = bitcast i32* %prov.pTmp01.0 to i16* +; CHECK-NEXT: %cmp = icmp slt i32 %i.0, %n +; CHECK-NEXT: br i1 %cmp, label %for.body, label %for.cond.cleanup +; CHECK: for.cond.cleanup: +; CHECK-NEXT: %8 = bitcast i32* %3 to i16* +; CHECK-NEXT: %9 = bitcast i32* %_pA to i16* +; CHECK-NEXT: store i16 99, i16* %9, ptr_provenance i16* %8, align 2, !tbaa !20, !noalias !19 +; CHECK-NEXT: %10 = bitcast i32* %pTmp00.0 to i16* +; CHECK-NEXT: store i16 42, i16* %10, ptr_provenance i16* %6, align 2, !tbaa !20, !noalias !19 +; CHECK-NEXT: %cmp5 = icmp sgt i32 %n, 5 +; CHECK-NEXT: %11 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %2, i8* %1, i32** null, i32** undef, i32 0, metadata !17) +; CHECK-NEXT: %prov.cond = select i1 %cmp5, i32* %prov.pTmp00.0, i32* %11 +; CHECK-NEXT: %12 = bitcast i32* %prov.cond to i16* +; CHECK-NEXT: %cond = select i1 %cmp5, i32* %pTmp00.0, i32* %2 +; CHECK-NEXT: %13 = bitcast i32* %cond to i16* +; CHECK-NEXT: store i16 43, i16* %13, ptr_provenance i16* %12, align 2, !tbaa !20, !noalias !19 +; CHECK-NEXT: ret void +; CHECK: for.body: +; CHECK-NEXT: %14 = bitcast i32* %pTmp01.0 to i16* +; CHECK-NEXT: %arrayidx3 = getelementptr inbounds i16, i16* %14, i32 1 +; CHECK-NEXT: %15 = load i16, i16* %arrayidx3, ptr_provenance i16* %7, align 2, !tbaa !20, !noalias !19 +; CHECK-NEXT: %16 = bitcast i32* %pTmp00.0 to i16* +; CHECK-NEXT: %arrayidx4 = getelementptr inbounds i16, i16* %16, i32 1 +; CHECK-NEXT: store i16 %15, i16* %arrayidx4, ptr_provenance i16* %6, align 2, !tbaa !20, !noalias !19 +; CHECK-NEXT: %inc = add nsw i32 %i.0, 1 +; CHECK-NEXT: br label %for.cond +; CHECK-NEXT: } + + + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #1 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) #2 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { argmemonly nounwind speculatable } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test_phi01: rpTmp"} +!4 = distinct !{!4, !"test_phi01"} +!5 = !{!6} +!6 = distinct !{!6, !4, !"test_phi01: rp2"} +!7 = !{!8, !8, i64 0, i64 4} +!8 = !{!9, i64 4, !"any pointer"} +!9 = !{!10, i64 1, !"omnipotent char"} +!10 = !{!"Simple C/C++ TBAA"} +!11 = !{!3, !6} +!12 = !{!13, !13, i64 0, i64 4} +!13 = !{!9, i64 4, !"int"} +!14 = !{!15} +!15 = distinct !{!15, !16, !"test_phi02: rpTmp"} +!16 = distinct !{!16, !"test_phi02"} +!17 = !{!18} +!18 = distinct !{!18, !16, !"test_phi02: rp2"} +!19 = !{!15, !18} +!20 = !{!21, !21, i64 0, i64 2} +!21 = !{!9, i64 2, !"short"} Index: llvm/test/Transforms/PropagateAndConvertNoAlias/struct.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PropagateAndConvertNoAlias/struct.ll @@ -0,0 +1,117 @@ +; RUN: opt < %s -convert-noalias -verify -S | FileCheck %s +; RUN: opt < %s -passes=convert-noalias,verify -S | FileCheck %s +target datalayout = "e-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f16:16:16-f32:32:32-f64:32:32-p:32:32:32:32:8-s0:32:32-a0:0:32-S32-n16:32-v128:32:32-P0-p0:32:32:32:32:8" + +%struct.FOO = type { i32*, i32*, i32* } + +; Function Attrs: nounwind +define dso_local void @test_rFOO(%struct.FOO* %_pFOO, i32* %_pA) #0 !noalias !2 { +entry: + %tmp = alloca %struct.FOO, align 4 + %0 = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.FOOs.i32(%struct.FOO** null, i32 0, metadata !5) + %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !7) + %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 4, metadata !7) + %3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 8, metadata !7) + %4 = call %struct.FOO* @llvm.noalias.p0s_struct.FOOs.p0i8.p0p0s_struct.FOOs.i32(%struct.FOO* %_pFOO, i8* %0, %struct.FOO** null, i32 0, metadata !5), !tbaa !9, !noalias !13 + %5 = call %struct.FOO* @llvm.noalias.copy.guard.p0s_struct.FOOs.p0i8(%struct.FOO* %4, i8* null, metadata !14, metadata !2) + %6 = load %struct.FOO, %struct.FOO* %5, align 4, !noalias !13 + %.fca.0.extract = extractvalue %struct.FOO %6, 0 + %.fca.1.extract = extractvalue %struct.FOO %6, 1 + %.fca.2.extract = extractvalue %struct.FOO %6, 2 + %7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %.fca.0.extract, i8* %1, i32** null, i32 0, metadata !7), !tbaa !18, !noalias !13 + %8 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %.fca.1.extract, i8* %2, i32** null, i32 4, metadata !7), !tbaa !20, !noalias !13 + %9 = load i32, i32* %8, align 4, !tbaa !21, !noalias !13 + store i32 %9, i32* %7, align 4, !tbaa !21, !noalias !13 + %10 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %1, i32** null, i32 0, metadata !7), !tbaa !18, !noalias !13 + store i32 42, i32* %10, align 4, !tbaa !21, !noalias !13 + %.fca.0.load.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %_pA, i8* %1, i32** null, i32 0, metadata !7) + %.fca.0.insert = insertvalue %struct.FOO undef, i32* %.fca.0.load.noalias, 0 + %.fca.1.load.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %.fca.1.extract, i8* %2, i32** null, i32 4, metadata !7) + %.fca.1.insert = insertvalue %struct.FOO %.fca.0.insert, i32* %.fca.1.load.noalias, 1 + %.fca.2.load.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32* %.fca.2.extract, i8* %3, i32** null, i32 8, metadata !7) + %.fca.2.insert = insertvalue %struct.FOO %.fca.1.insert, i32* %.fca.2.load.noalias, 2 + call void @fum(%struct.FOO %.fca.2.insert), !noalias !13 + ret void +} + +; CHECK-LABEL: @test_rFOO( +; CHECK-NEXT: entry: +; CHECK-NEXT: %tmp = alloca %struct.FOO, align 4 +; CHECK-NEXT: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0s_struct.FOOs.i32(%struct.FOO** null, i32 0, metadata !5) +; CHECK-NEXT: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 0, metadata !7) +; CHECK-NEXT: %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 4, metadata !7) +; CHECK-NEXT: %3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32** null, i32 8, metadata !7) +; CHECK-NEXT: %4 = call %struct.FOO* @llvm.provenance.noalias.p0s_struct.FOOs.p0i8.p0p0s_struct.FOOs.p0p0s_struct.FOOs.i32(%struct.FOO* %_pFOO, i8* %0, %struct.FOO** null, %struct.FOO** undef, i32 0, metadata !5), !tbaa !9, !noalias !13 +; CHECK-NEXT: %.guard = call %struct.FOO* @llvm.noalias.arg.guard.p0s_struct.FOOs.p0s_struct.FOOs(%struct.FOO* %_pFOO, %struct.FOO* %4) +; CHECK-NEXT: %5 = call %struct.FOO* @llvm.noalias.copy.guard.p0s_struct.FOOs.p0i8(%struct.FOO* %.guard, i8* null, metadata !14, metadata !2) +; CHECK-NEXT: %6 = load %struct.FOO, %struct.FOO* %5, align 4, !noalias !13 +; CHECK-NEXT: %.fca.0.extract = extractvalue %struct.FOO %6, 0 +; CHECK-NEXT: %.fca.1.extract = extractvalue %struct.FOO %6, 1 +; CHECK-NEXT: %.fca.2.extract = extractvalue %struct.FOO %6, 2 +; CHECK-NEXT: %7 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %.fca.0.extract, i8* %1, i32** null, i32** undef, i32 0, metadata !7), !tbaa !18, !noalias !13 +; CHECK-NEXT: %8 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %.fca.1.extract, i8* %2, i32** null, i32** undef, i32 4, metadata !7), !tbaa !20, !noalias !13 +; CHECK-NEXT: %9 = load i32, i32* %.fca.1.extract, ptr_provenance i32* %8, align 4, !tbaa !21, !noalias !13 +; CHECK-NEXT: store i32 %9, i32* %.fca.0.extract, ptr_provenance i32* %7, align 4, !tbaa !21, !noalias !13 +; CHECK-NEXT: %10 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %_pA, i8* %1, i32** null, i32** undef, i32 0, metadata !7), !tbaa !18, !noalias !13 +; CHECK-NEXT: store i32 42, i32* %_pA, ptr_provenance i32* %10, align 4, !tbaa !21, !noalias !13 +; CHECK-NEXT: %.fca.0.load.noalias.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %_pA, i32* %10) +; CHECK-NEXT: %.fca.0.insert = insertvalue %struct.FOO undef, i32* %.fca.0.load.noalias.guard, 0 +; CHECK-NEXT: %.fca.1.load.noalias.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %.fca.1.extract, i32* %8) +; CHECK-NEXT: %.fca.1.insert = insertvalue %struct.FOO %.fca.0.insert, i32* %.fca.1.load.noalias.guard, 1 +; CHECK-NEXT: %11 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i32(i32* %.fca.2.extract, i8* %3, i32** null, i32** undef, i32 8, metadata !7) +; CHECK-NEXT: %.fca.2.load.noalias.guard = call i32* @llvm.noalias.arg.guard.p0i32.p0i32(i32* %.fca.2.extract, i32* %11) +; CHECK-NEXT: %.fca.2.insert = insertvalue %struct.FOO %.fca.1.insert, i32* %.fca.2.load.noalias.guard, 2 +; CHECK-NEXT: call void @fum(%struct.FOO %.fca.2.insert), !noalias !13 +; CHECK-NEXT: ret void +; CHECK-NEXT: } + + +; Function Attrs: argmemonly nounwind speculatable +declare %struct.FOO* @llvm.noalias.p0s_struct.FOOs.p0i8.p0p0s_struct.FOOs.i32(%struct.FOO*, i8*, %struct.FOO**, i32, metadata) #1 + +; Function Attrs: nounwind readnone +declare %struct.FOO* @llvm.noalias.copy.guard.p0s_struct.FOOs.p0i8(%struct.FOO*, i8*, metadata, metadata) #2 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i32(i32*, i8*, i32**, i32, metadata) #1 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i32(i32**, i32, metadata) #3 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0s_struct.FOOs.i32(%struct.FOO**, i32, metadata) #3 + +declare dso_local void @fum(%struct.FOO) #4 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind speculatable } +attributes #2 = { nounwind readnone } +attributes #3 = { argmemonly nounwind } +attributes #4 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3} +!3 = distinct !{!3, !4, !"test_rFOO: unknown scope"} +!4 = distinct !{!4, !"test_rFOO"} +!5 = !{!6} +!6 = distinct !{!6, !4, !"test_rFOO: rpFOO"} +!7 = !{!8} +!8 = distinct !{!8, !4, !"test_rFOO: tmp"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!11, i64 4, !"any pointer"} +!11 = !{!12, i64 1, !"omnipotent char"} +!12 = !{!"Simple C/C++ TBAA"} +!13 = !{!6, !8, !3} +!14 = !{!15, !16, !17} +!15 = !{i64 -1, i64 0} +!16 = !{i64 -1, i64 1} +!17 = !{i64 -1, i64 2} +!18 = !{!19, !10, i64 0, i64 4} +!19 = !{!11, i64 12, !"FOO", !10, i64 0, i64 4, !10, i64 4, i64 4, !10, i64 8, i64 4} +!20 = !{!19, !10, i64 4, i64 4} +!21 = !{!22, !22, i64 0, i64 4} +!22 = !{!11, i64 4, !"int"} Index: llvm/test/Transforms/SLPVectorizer/noalias.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/SLPVectorizer/noalias.ll @@ -0,0 +1,55 @@ +; RUN: opt -S < %s -slp-vectorizer -slp-max-reg-size=128 -slp-min-reg-size=128 | FileCheck %s + +; SLP vectorization across a @llvm.provenance.noalias and provenance + +; Function Attrs: inaccessiblememonly nounwind willreturn +declare void @llvm.sideeffect() #0 + +define void @test(float* %p) { +; CHECK-LABEL: @test( +; CHECK-NEXT: [[P1_DECL:%.*]] = tail call i8* @llvm.noalias.decl.p0i8.p0p0f32.i32(float** null, i32 0, metadata !0) +; CHECK-NEXT: [[P0:%.*]] = getelementptr float, float* [[P:%.*]], i64 0 +; CHECK-NEXT: [[P1:%.*]] = getelementptr float, float* [[P]], i64 1 +; CHECK-NEXT: [[PROVENANCE_P1:%.*]] = tail call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* [[P1]], i8* [[P1_DECL]], float** null, float** undef, i32 0, metadata !0), !noalias !0 +; CHECK-NEXT: [[P2:%.*]] = getelementptr float, float* [[P]], i64 2 +; CHECK-NEXT: [[P3:%.*]] = getelementptr float, float* [[P]], i64 3 +; CHECK-NEXT: call void @llvm.sideeffect() +; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[P0]] to <4 x float>* +; CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, <4 x float>* [[TMP1]], align 4 +; CHECK-NEXT: call void @llvm.sideeffect() +; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[P0]] to <4 x float>* +; CHECK-NEXT: store <4 x float> [[TMP2]], <4 x float>* [[TMP3]], align 4 +; CHECK-NEXT: ret void +; + %p1.decl = tail call i8* @llvm.noalias.decl.p0i8.p0p0f32.i32(float** null, i32 0, metadata !0) + %p0 = getelementptr float, float* %p, i64 0 + %p1 = getelementptr float, float* %p, i64 1 + %prov.p1 = tail call float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float* %p1, i8* %p1.decl, float** null, float** undef, i32 0, metadata !0), !noalias !0 + %p2 = getelementptr float, float* %p, i64 2 + %p3 = getelementptr float, float* %p, i64 3 + %l0 = load float, float* %p0, !noalias !0 + %l1 = load float, float* %p1, ptr_provenance float* %prov.p1, !noalias !0 + %l2 = load float, float* %p2, !noalias !0 + call void @llvm.sideeffect() + %l3 = load float, float* %p3, !noalias !0 + store float %l0, float* %p0, !noalias !0 + call void @llvm.sideeffect() + store float %l1, float* %p1, ptr_provenance float* %prov.p1, !noalias !0 + store float %l2, float* %p2, !noalias !0 + store float %l3, float* %p3, !noalias !0 + ret void +} + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0f32.i32(float**, i32, metadata) #1 + +; Function Attrs: nounwind readnone speculatable +declare float* @llvm.provenance.noalias.p0f32.p0i8.p0p0f32.p0p0f32.i32(float*, i8*, float**, float**, i32, metadata) #2 + +attributes #0 = { inaccessiblememonly nounwind willreturn } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind readnone speculatable } + +!0 = !{!1} +!1 = distinct !{!1, !2, !"test_f: p"} +!2 = distinct !{!2, !"test_f"} Index: llvm/test/Transforms/SROA/noalias.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/SROA/noalias.ll @@ -0,0 +1,302 @@ +; RUN: opt < %s -sroa -S | FileCheck %s +; RUN: opt < %s -passes=sroa -S | FileCheck %s + +target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" + + +%struct.FOO = type { i32*, i32*, i32* } + +; Function Attrs: nounwind +define dso_local void @test_ri(i32* %_p) #0 { +entry: + %_p.addr = alloca i32*, align 4 + %rp = alloca i32*, align 4 + store i32* %_p, i32** %_p.addr, align 4, !tbaa !2, !noalias !6 + store i32* undef, i32** %rp, align 4, !noalias !6 + %0 = bitcast i32** %rp to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* %0) #4, !noalias !6 + %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** %rp, i64 0, metadata !6) + %2 = load i32*, i32** %_p.addr, align 4, !tbaa !2, !noalias !6 + store i32* %2, i32** %rp, align 4, !tbaa !2, !noalias !6 + %3 = load i32*, i32** %rp, align 4, !tbaa !2, !noalias !6 + %4 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %3, i8* %1, i32** %rp, i64 0, metadata !6), !tbaa !2, !noalias !6 + store i32 42, i32* %4, align 4, !tbaa !9, !noalias !6 + %5 = bitcast i32** %rp to i8* + call void @llvm.lifetime.end.p0i8(i64 4, i8* %5) #4 + ret void +} + +; CHECK-LABEL: @test_ri( +; CHECK-NOT: alloca +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !2) +; CHECK: %1 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %_p, i8* %0, i32** null, i64 0, metadata !2), !tbaa !5, !noalias !2 + +; Function Attrs: nounwind +define dso_local void @test_ra(i32* %_p) #0 { +entry: + %_p.addr = alloca i32*, align 4 + %rp = alloca [3 x i32*], align 4 + store i32* %_p, i32** %_p.addr, align 4, !tbaa !2, !noalias !11 + store [3 x i32*] undef, [3 x i32*]* %rp, align 4, !noalias !11 + %0 = bitcast [3 x i32*]* %rp to i8* + call void @llvm.lifetime.start.p0i8(i64 12, i8* %0) #4, !noalias !11 + %1 = call i8* @llvm.noalias.decl.p0i8.p0a3p0i32.i64([3 x i32*]* %rp, i64 0, metadata !11) + %arrayinit.begin = getelementptr inbounds [3 x i32*], [3 x i32*]* %rp, i32 0, i32 0 + %2 = load i32*, i32** %_p.addr, align 4, !tbaa !2, !noalias !11 + store i32* %2, i32** %arrayinit.begin, align 4, !tbaa !2, !noalias !11 + %arrayinit.element = getelementptr inbounds i32*, i32** %arrayinit.begin, i32 1 + %3 = load i32*, i32** %_p.addr, align 4, !tbaa !2, !noalias !11 + %add.ptr = getelementptr inbounds i32, i32* %3, i32 1 + store i32* %add.ptr, i32** %arrayinit.element, align 4, !tbaa !2, !noalias !11 + %arrayinit.element1 = getelementptr inbounds i32*, i32** %arrayinit.element, i32 1 + %4 = load i32*, i32** %_p.addr, align 4, !tbaa !2, !noalias !11 + %add.ptr2 = getelementptr inbounds i32, i32* %4, i32 2 + store i32* %add.ptr2, i32** %arrayinit.element1, align 4, !tbaa !2, !noalias !11 + %arrayidx = getelementptr inbounds [3 x i32*], [3 x i32*]* %rp, i32 0, i32 0 + %5 = load i32*, i32** %arrayidx, align 4, !tbaa !2, !noalias !11 + %6 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %5, i8* %1, i32** %arrayidx, i64 0, metadata !11), !tbaa !2, !noalias !11 + store i32 42, i32* %6, align 4, !tbaa !9, !noalias !11 + %arrayidx3 = getelementptr inbounds [3 x i32*], [3 x i32*]* %rp, i32 0, i32 1 + %7 = load i32*, i32** %arrayidx3, align 4, !tbaa !2, !noalias !11 + %8 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %7, i8* %1, i32** %arrayidx3, i64 0, metadata !11), !tbaa !2, !noalias !11 + store i32 43, i32* %8, align 4, !tbaa !9, !noalias !11 + %arrayidx4 = getelementptr inbounds [3 x i32*], [3 x i32*]* %rp, i32 0, i32 2 + %9 = load i32*, i32** %arrayidx4, align 4, !tbaa !2, !noalias !11 + %10 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %9, i8* %1, i32** %arrayidx4, i64 0, metadata !11), !tbaa !2, !noalias !11 + store i32 44, i32* %10, align 4, !tbaa !9, !noalias !11 + %11 = bitcast [3 x i32*]* %rp to i8* + call void @llvm.lifetime.end.p0i8(i64 12, i8* %11) #4 + ret void +} + +; CHECK-LABEL: @test_ra( +; CHECK-NOT: alloca +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !11) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 8, metadata !11) +; CHECK: %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 16, metadata !11) +; CHECK: %3 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %_p, i8* %0, i32** null, i64 0, metadata !11), !tbaa !5, !noalias !11 +; CHECK: %4 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %add.ptr, i8* %1, i32** null, i64 8, metadata !11), !tbaa !5, !noalias !11 +; CHECK: %5 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %add.ptr2, i8* %2, i32** null, i64 16, metadata !11), !tbaa !5, !noalias !11 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0a3p0i32.i64([3 x i32*]*, i64, metadata) #1 + +; Function Attrs: nounwind +define dso_local void @test_rs(i32* %_p) #0 { +entry: + %_p.addr = alloca i32*, align 4 + %foo = alloca %struct.FOO, align 4 + store i32* %_p, i32** %_p.addr, align 4, !tbaa !2, !noalias !14 + store %struct.FOO undef, %struct.FOO* %foo, align 4, !noalias !14 + %0 = bitcast %struct.FOO* %foo to i8* + call void @llvm.lifetime.start.p0i8(i64 12, i8* %0) #4, !noalias !14 + %1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FOOs.i64(%struct.FOO* %foo, i64 0, metadata !14) + %mP0 = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 0 + %2 = load i32*, i32** %_p.addr, align 4, !tbaa !2, !noalias !14 + store i32* %2, i32** %mP0, align 4, !tbaa !17, !noalias !14 + %mP1 = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 1 + %3 = load i32*, i32** %_p.addr, align 4, !tbaa !2, !noalias !14 + %add.ptr = getelementptr inbounds i32, i32* %3, i32 1 + store i32* %add.ptr, i32** %mP1, align 4, !tbaa !19, !noalias !14 + %mP2 = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 2 + %4 = load i32*, i32** %_p.addr, align 4, !tbaa !2, !noalias !14 + %add.ptr1 = getelementptr inbounds i32, i32* %4, i32 2 + store i32* %add.ptr1, i32** %mP2, align 4, !tbaa !20, !noalias !14 + %mP02 = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 0 + %5 = load i32*, i32** %mP02, align 4, !tbaa !17, !noalias !14 + %6 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %5, i8* %1, i32** %mP02, i64 0, metadata !14), !tbaa !17, !noalias !14 + store i32 42, i32* %6, align 4, !tbaa !9, !noalias !14 + %mP13 = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 1 + %7 = load i32*, i32** %mP13, align 4, !tbaa !19, !noalias !14 + %8 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %7, i8* %1, i32** %mP13, i64 0, metadata !14), !tbaa !19, !noalias !14 + store i32 43, i32* %8, align 4, !tbaa !9, !noalias !14 + %mP24 = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 2 + %9 = load i32*, i32** %mP24, align 4, !tbaa !20, !noalias !14 + %10 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %9, i8* %1, i32** %mP24, i64 0, metadata !14), !tbaa !20, !noalias !14 + store i32 44, i32* %10, align 4, !tbaa !9, !noalias !14 + %11 = bitcast %struct.FOO* %foo to i8* + call void @llvm.lifetime.end.p0i8(i64 12, i8* %11) #4 + ret void +} + +; CHECK-LABEL: @test_rs( +; CHECK-NOT: alloca +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !14) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 8, metadata !14) +; CHECK: %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 16, metadata !14) +; CHECK: %3 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %_p, i8* %0, i32** null, i64 0, metadata !14), !tbaa !17, !noalias !14 +; CHECK: %4 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %add.ptr, i8* %1, i32** null, i64 8, metadata !14), !tbaa !19, !noalias !14 +; CHECK: %5 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %add.ptr1, i8* %2, i32** null, i64 16, metadata !14), !tbaa !20, !noalias !14 + +; Function Attrs: argmemonly nounwind speculatable +define dso_local void @test_ri_inlined(i32* %_p) local_unnamed_addr #2 !noalias !21 { +entry: + %rp = alloca i32*, align 4 + %0 = bitcast i32** %rp to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #4, !noalias !24 + %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** nonnull %rp, i64 0, metadata !27), !noalias !21 + store i32* %_p, i32** %rp, ptr_provenance i32** undef, align 4, !noalias !24 + %2 = load i32*, i32** %rp, ptr_provenance i32** undef, align 4, !noalias !28 + %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %2, i8* %1, i32** %rp, i32** undef, i64 0, metadata !27) #4, !noalias !28 + store i32 42, i32* %2, ptr_provenance i32* %3, align 4, !noalias !28 + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #4, !noalias !21 + ret void +} + +; CHECK-LABEL: @test_ri_inlined( +; CHECK-NOT: alloca +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !24) +; CHECK: %1 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %_p, i8* %0, i32** null, i32** undef, i64 0, metadata !24){{.*}}, !noalias !27 + +; Function Attrs: argmemonly nounwind speculatable +define dso_local void @test_ra_inlined(i32* %_p) local_unnamed_addr #2 !noalias !29 { +entry: + %rp = alloca [3 x i32*], align 4 + %.fca.0.gep = getelementptr inbounds [3 x i32*], [3 x i32*]* %rp, i32 0, i32 0 + %0 = bitcast [3 x i32*]* %rp to i8* + call void @llvm.lifetime.start.p0i8(i64 12, i8* nonnull %0) #4, !noalias !32 + %1 = call i8* @llvm.noalias.decl.p0i8.p0a3p0i32.i64([3 x i32*]* nonnull %rp, i64 0, metadata !35), !noalias !29 + store i32* %_p, i32** %.fca.0.gep, ptr_provenance i32** undef, align 4, !noalias !32 + %arrayinit.element = getelementptr inbounds [3 x i32*], [3 x i32*]* %rp, i32 0, i32 1 + %add.ptr = getelementptr inbounds i32, i32* %_p, i32 1 + store i32* %add.ptr, i32** %arrayinit.element, ptr_provenance i32** undef, align 4, !noalias !32 + %arrayinit.element1 = getelementptr inbounds [3 x i32*], [3 x i32*]* %rp, i32 0, i32 2 + %add.ptr2 = getelementptr inbounds i32, i32* %_p, i32 2 + store i32* %add.ptr2, i32** %arrayinit.element1, ptr_provenance i32** undef, align 4, !noalias !32 + %2 = load i32*, i32** %.fca.0.gep, ptr_provenance i32** undef, align 4, !noalias !36 + %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %2, i8* %1, i32** %.fca.0.gep, i32** undef, i64 0, metadata !35) #4, !noalias !36 + store i32 42, i32* %2, ptr_provenance i32* %3, align 4, !noalias !36 + %arrayidx1.i = getelementptr inbounds i32*, i32** %.fca.0.gep, i32 1 + %4 = load i32*, i32** %arrayidx1.i, ptr_provenance i32** undef, align 4, !noalias !36 + %5 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %4, i8* %1, i32** nonnull %arrayidx1.i, i32** undef, i64 0, metadata !35) #4, !noalias !36 + store i32 43, i32* %4, ptr_provenance i32* %5, align 4, !noalias !36 + %arrayidx2.i = getelementptr inbounds i32*, i32** %.fca.0.gep, i32 2 + %6 = load i32*, i32** %arrayidx2.i, ptr_provenance i32** undef, align 4, !noalias !36 + %7 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %6, i8* %1, i32** nonnull %arrayidx2.i, i32** undef, i64 0, metadata !35) #4, !noalias !36 + store i32 44, i32* %6, ptr_provenance i32* %7, align 4, !noalias !36 + call void @llvm.lifetime.end.p0i8(i64 12, i8* nonnull %0) #4, !noalias !29 + ret void +} + +; CHECK-LABEL: @test_ra_inlined( +; CHECK-NOT: alloca +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !31) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 8, metadata !31) +; CHECK: %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 16, metadata !31) +; CHECK: %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %_p, i8* %0, i32** null, i32** undef, i64 0, metadata !31){{.*}}, !noalias !34 +; CHECK: %4 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %add.ptr, i8* %1, i32** nonnull null, i32** undef, i64 8, metadata !31){{.*}}, !noalias !34 +; CHECK: %5 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %add.ptr2, i8* %2, i32** nonnull null, i32** undef, i64 16, metadata !31){{.*}}, !noalias !34 + + +; Function Attrs: argmemonly nounwind speculatable +define dso_local void @test_rs_inlined(i32* %_p) local_unnamed_addr #2 !noalias !37 { +entry: + %foo = alloca %struct.FOO, align 4 + %.fca.0.gep = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 0 + %.fca.1.gep = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 1 + %.fca.2.gep = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 2 + %0 = bitcast %struct.FOO* %foo to i8* + call void @llvm.lifetime.start.p0i8(i64 12, i8* nonnull %0) #4, !noalias !40 + %1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FOOs.i64(%struct.FOO* nonnull %foo, i64 0, metadata !43), !noalias !37 + store i32* %_p, i32** %.fca.0.gep, ptr_provenance i32** undef, align 4, !noalias !40 + %add.ptr = getelementptr inbounds i32, i32* %_p, i32 1 + store i32* %add.ptr, i32** %.fca.1.gep, ptr_provenance i32** undef, align 4, !noalias !40 + %add.ptr1 = getelementptr inbounds i32, i32* %_p, i32 2 + store i32* %add.ptr1, i32** %.fca.2.gep, ptr_provenance i32** undef, align 4, !noalias !40 + %mP0.i = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 0 + %2 = load i32*, i32** %mP0.i, ptr_provenance i32** undef, align 4, !noalias !44 + %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %2, i8* %1, i32** %mP0.i, i32** undef, i64 0, metadata !43) #4, !noalias !44 + store i32 42, i32* %2, ptr_provenance i32* %3, align 4, !noalias !44 + %mP1.i = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 1 + %4 = load i32*, i32** %mP1.i, ptr_provenance i32** undef, align 4, !noalias !44 + %5 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %4, i8* %1, i32** nonnull %mP1.i, i32** undef, i64 0, metadata !43) #4, !noalias !44 + store i32 43, i32* %4, ptr_provenance i32* %5, align 4, !noalias !44 + %mP2.i = getelementptr inbounds %struct.FOO, %struct.FOO* %foo, i32 0, i32 2 + %6 = load i32*, i32** %mP2.i, ptr_provenance i32** undef, align 4, !noalias !44 + %7 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %6, i8* %1, i32** nonnull %mP2.i, i32** undef, i64 0, metadata !43) #4, !noalias !44 + store i32 44, i32* %6, ptr_provenance i32* %7, align 4, !noalias !44 + call void @llvm.lifetime.end.p0i8(i64 12, i8* nonnull %0) #4, !noalias !37 + ret void +} + +; CHECK-LABEL: @test_rs_inlined( +; CHECK-NOT: alloca +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !38) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 8, metadata !38) +; CHECK: %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 16, metadata !38) +; CHECK: %3 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %_p, i8* %0, i32** null, i32** undef, i64 0, metadata !38){{.*}}, !noalias !41 +; CHECK: %4 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %add.ptr, i8* %1, i32** nonnull null, i32** undef, i64 8, metadata !38){{.*}}, !noalias !41 +; CHECK: %5 = call i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32* %add.ptr1, i8* %2, i32** nonnull null, i32** undef, i64 16, metadata !38){{.*}}, !noalias !41 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0s_struct.FOOs.i64(%struct.FOO*, i64, metadata) #1 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32**, i64, metadata) #1 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32*, i8*, i32**, i64, metadata) #2 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + +; Function Attrs: nounwind readnone speculatable +declare i32* @llvm.provenance.noalias.p0i32.p0i8.p0p0i32.p0p0i32.i64(i32*, i8*, i32**, i32**, i64, metadata) #3 + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { argmemonly nounwind speculatable } +attributes #3 = { nounwind readnone speculatable } +attributes #4 = { nounwind } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang"} +!2 = !{!3, !3, i64 0, i64 4} +!3 = !{!4, i64 4, !"any pointer"} +!4 = !{!5, i64 1, !"omnipotent char"} +!5 = !{!"Simple C/C++ TBAA"} +!6 = !{!7} +!7 = distinct !{!7, !8, !"test_ri: rp"} +!8 = distinct !{!8, !"test_ri"} +!9 = !{!10, !10, i64 0, i64 4} +!10 = !{!4, i64 4, !"int"} +!11 = !{!12} +!12 = distinct !{!12, !13, !"test_ra: rp"} +!13 = distinct !{!13, !"test_ra"} +!14 = !{!15} +!15 = distinct !{!15, !16, !"test_rs: foo"} +!16 = distinct !{!16, !"test_rs"} +!17 = !{!18, !3, i64 0, i64 4} +!18 = !{!4, i64 12, !"FOO", !3, i64 0, i64 4, !3, i64 4, i64 4, !3, i64 8, i64 4} +!19 = !{!18, !3, i64 4, i64 4} +!20 = !{!18, !3, i64 8, i64 4} +!21 = !{!22} +!22 = distinct !{!22, !23, !"test_ri_inlined: unknown scope"} +!23 = distinct !{!23, !"test_ri_inlined"} +!24 = !{!25, !22} +!25 = distinct !{!25, !26, !"test_ri_inlined: rp"} +!26 = distinct !{!26, !"test_ri_inlined"} +!27 = !{!25} +!28 = !{!22, !25, !22} +!29 = !{!30} +!30 = distinct !{!30, !31, !"test_ra_inlined: unknown scope"} +!31 = distinct !{!31, !"test_ra_inlined"} +!32 = !{!33, !30} +!33 = distinct !{!33, !34, !"test_ra_inlined: rp"} +!34 = distinct !{!34, !"test_ra_inlined"} +!35 = !{!33} +!36 = !{!30, !33, !30} +!37 = !{!38} +!38 = distinct !{!38, !39, !"test_rs_inlined: unknown scope"} +!39 = distinct !{!39, !"test_rs_inlined"} +!40 = !{!41, !38} +!41 = distinct !{!41, !42, !"test_rs_inlined: foo"} +!42 = distinct !{!42, !"test_rs_inlined"} +!43 = !{!41} +!44 = !{!38, !41, !38} Index: llvm/test/Transforms/SROA/noalias2.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/SROA/noalias2.ll @@ -0,0 +1,463 @@ +; RUN: opt < %s -sroa -S | FileCheck %s --check-prefixes=CHECK +; RUN: opt < %s -passes=sroa -S | FileCheck %s --check-prefixes=CHECK + + +; Share the dependency on llvm.noalias.copy.guard: +; RUN: sed < %s -e 's/tmp18,/tmp10,/' -e 's/cp3,/cp2,/' | opt -sroa -S | FileCheck %s --check-prefixes=CHECK,CHECK_S +; RUN: sed < %s -e 's/tmp18,/tmp10,/' -e 's/cp3,/cp2,/' | opt -passes=sroa -S | FileCheck %s --check-prefixes=CHECK,CHECK_S + +; Validate that SROA correctly deduces noalias pointers when removing: +; - llvm.mempcy +; - aggregate load/store +; - copying the struct through i64 + +; General form of each function is based on: +; ------ +; struct FOO { +; int* __restrict p; +; }; +; +; struct FUM { +; int* __restrict p0; +; struct FOO m1; +; }; +; +; void testXXXXXX(struct FUM* a_fum) // Scope A +; { +; struct FUM l_fum = *a_fum; // Scope B +; { +; struct FUM l2_fum = l_fum; // Scope C1 +; +; *l2_fum.p0 = 42; +; } +; { +; struct FUM l3_fum = l_fum; // Scope C2 +; +; *l3_fum.m1.p = 43; +; } +; } +; ---- +; After SROA, we expect to see following llvm.noalias dependencies: +; store 42 -> C1 -> B -> A +; store 43 -> C2 -> B -> A + + +; ModuleID = 'test.c' +source_filename = "test.c" +target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" +target triple = "i386-unknown-linux-gnu" + +%struct.FUM = type { i32*, %struct.FOO } +%struct.FOO = type { i32* } + +; Function Attrs: nounwind +define dso_local void @test01_memcpy(%struct.FUM* %a_fum) #0 !noalias !3 { +entry: + %a_fum.addr = alloca %struct.FUM*, align 4 + %l_fum = alloca %struct.FUM, align 4 + %l2_fum = alloca %struct.FUM, align 4 + %l3_fum = alloca %struct.FUM, align 4 + store %struct.FUM* %a_fum, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !10 + %tmp0 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp0) #5, !noalias !10 + %tmp1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l_fum, i64 0, metadata !12), !noalias !10 + %tmp2 = load %struct.FUM*, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !10 + %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %tmp2, i8* null, metadata !13, metadata !3) + %tmp4 = bitcast %struct.FUM* %l_fum to i8* + %tmp5 = bitcast %struct.FUM* %tmp3 to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %tmp4, i8* align 4 %tmp5, i32 8, i1 false), !tbaa.struct !16, !noalias !10 + %tmp6 = bitcast %struct.FUM* %l2_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp6) #5, !noalias !17 + %tmp7 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l2_fum, i64 0, metadata !19), !noalias !17 + %tmp8 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %l_fum, i8* %tmp1, metadata !13, metadata !12) + %tmp9 = bitcast %struct.FUM* %l2_fum to i8* + %tmp10 = bitcast %struct.FUM* %tmp8 to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %tmp9, i8* align 4 %tmp10, i32 8, i1 false), !tbaa.struct !16, !noalias !17 + %p0 = getelementptr inbounds %struct.FUM, %struct.FUM* %l2_fum, i32 0, i32 0 + %tmp11 = load i32*, i32** %p0, align 4, !tbaa !20, !noalias !17 + %tmp12 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp11, i8* %tmp7, i32** %p0, i64 0, metadata !19), !tbaa !20, !noalias !17 + store i32 42, i32* %tmp12, align 4, !tbaa !23, !noalias !17 + %tmp13 = bitcast %struct.FUM* %l2_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp13) #5, !noalias !10 + %tmp14 = bitcast %struct.FUM* %l3_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp14) #5, !noalias !25 + %tmp15 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l3_fum, i64 0, metadata !27), !noalias !25 + %tmp16 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %l_fum, i8* %tmp1, metadata !13, metadata !12) + %tmp17 = bitcast %struct.FUM* %l3_fum to i8* + %tmp18 = bitcast %struct.FUM* %tmp16 to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %tmp17, i8* align 4 %tmp18, i32 8, i1 false), !tbaa.struct !16, !noalias !25 + %m1 = getelementptr inbounds %struct.FUM, %struct.FUM* %l3_fum, i32 0, i32 1 + %p = getelementptr inbounds %struct.FOO, %struct.FOO* %m1, i32 0, i32 0 + %tmp19 = load i32*, i32** %p, align 4, !tbaa !28, !noalias !25 + %tmp20 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp19, i8* %tmp15, i32** %p, i64 0, metadata !27), !tbaa !28, !noalias !25 + store i32 43, i32* %tmp20, align 4, !tbaa !23, !noalias !25 + %tmp21 = bitcast %struct.FUM* %l3_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp21) #5, !noalias !10 + %tmp22 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp22) #5 + ret void +} + +; CHECK-LABEL: @test01_memcpy +; CHECK-NOT: alloca +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !6) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !6) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %l_fum.sroa.0.0.l_fum.sroa.0.0.copyload.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %l_fum.sroa.0.0.copyload, i8* null, i32** %l_fum.sroa.0.0.tmp5.sroa_idx, i64 0, metadata !3) +; CHECK: %l_fum.sroa.[[SROA:[0-9]+]].0.tmp5.sroa_[[IDX3:idx[0-9]+]] = getelementptr inbounds %struct.FUM, %struct.FUM* %a_fum, i32 0, i32 1, i32 0 +; CHECK: %l_fum.sroa.[[SROA]].0.l_fum.sroa.[[SROA]].0.copyload.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %l_fum.sroa.[[SROA]].0.copyload, i8* null, i32** %l_fum.sroa.[[SROA]].0.tmp5.sroa_[[IDX3]], i64 0, metadata !3) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !15) +; CHECK: %3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !15) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %l2_fum.sroa.0.0.l2_fum.sroa.0.0.copyload.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %l_fum.sroa.0.0.l_fum.sroa.0.0.copyload.noalias, i8* %0, i32** null, i64 0, metadata !6) +; CHECK: %l2_fum.sroa.7.0.l2_fum.sroa.7.0.copyload.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %l_fum.sroa.[[SROA]].0.l_fum.sroa.[[SROA]].0.copyload.noalias, i8* %1, i32** null, i64 4, metadata !6) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %tmp12 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %l2_fum.sroa.0.0.l2_fum.sroa.0.0.copyload.noalias, i8* %2, i32** null, i64 0, metadata !15), !tbaa !17, !noalias !20 +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %4 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !23) +; CHECK: %5 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !23) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %l3_fum.sroa.0.0.l3_fum.sroa.0.0.copyload.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %l_fum.sroa.0.0.l_fum.sroa.0.0.copyload.noalias, i8* %0, i32** null, i64 0, metadata !6) +; CHECK: %l3_fum.sroa.5.0.l3_fum.sroa.5.0.copyload.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %l_fum.sroa.[[SROA]].0.l_fum.sroa.[[SROA]].0.copyload.noalias, i8* %1, i32** null, i64 4, metadata !6) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %tmp20 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %l3_fum.sroa.5.0.l3_fum.sroa.5.0.copyload.noalias, i8* %5, i32** null, i64 4, metadata !23), !tbaa !25, !noalias !26 +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: ret void + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg %0, i8* nocapture %1) #1 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %0, i64 %1, metadata %2) #2 + +; Function Attrs: nounwind readnone +declare %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %0, i8* %1, metadata %2, metadata %3) #3 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly %0, i8* noalias nocapture readonly %1, i32 %2, i1 immarg %3) #1 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %0, i8* %1, i32** %2, i64 %3, metadata %4) #4 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg %0, i8* nocapture %1) #1 + +; Function Attrs: nounwind +define dso_local void @test02_aggloadstore(%struct.FUM* %a_fum) #0 !noalias !29 { +entry: + %a_fum.addr = alloca %struct.FUM*, align 4 + %l_fum = alloca %struct.FUM, align 4 + %l2_fum = alloca %struct.FUM, align 4 + %l3_fum = alloca %struct.FUM, align 4 + store %struct.FUM* %a_fum, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !32 + %tmp0 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp0) #5, !noalias !32 + %tmp1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l_fum, i64 0, metadata !34), !noalias !32 + %tmp2 = load %struct.FUM*, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !32 + %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %tmp2, i8* null, metadata !13, metadata !29) + %cp1 = load %struct.FUM, %struct.FUM* %tmp3, align 4 + store %struct.FUM %cp1, %struct.FUM* %l_fum, align 4 + %tmp6 = bitcast %struct.FUM* %l2_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp6) #5, !noalias !35 + %tmp7 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l2_fum, i64 0, metadata !37), !noalias !35 + %tmp8 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %l_fum, i8* %tmp1, metadata !13, metadata !34) + %cp2 = load %struct.FUM, %struct.FUM* %tmp8, align 4 + store %struct.FUM %cp2, %struct.FUM* %l2_fum, align 4 + %p0 = getelementptr inbounds %struct.FUM, %struct.FUM* %l2_fum, i32 0, i32 0 + %tmp11 = load i32*, i32** %p0, align 4, !tbaa !20, !noalias !35 + %tmp12 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp11, i8* %tmp7, i32** %p0, i64 0, metadata !37), !tbaa !20, !noalias !35 + store i32 42, i32* %tmp12, align 4, !tbaa !23, !noalias !35 + %tmp13 = bitcast %struct.FUM* %l2_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp13) #5, !noalias !32 + %tmp14 = bitcast %struct.FUM* %l3_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp14) #5, !noalias !38 + %tmp15 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l3_fum, i64 0, metadata !40), !noalias !38 + %tmp16 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %l_fum, i8* %tmp1, metadata !13, metadata !34) + %cp3 = load %struct.FUM, %struct.FUM* %tmp16, align 4 + store %struct.FUM %cp3, %struct.FUM* %l3_fum, align 4 + %m1 = getelementptr inbounds %struct.FUM, %struct.FUM* %l3_fum, i32 0, i32 1 + %p = getelementptr inbounds %struct.FOO, %struct.FOO* %m1, i32 0, i32 0 + %tmp19 = load i32*, i32** %p, align 4, !tbaa !28, !noalias !38 + %tmp20 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp19, i8* %tmp15, i32** %p, i64 0, metadata !40), !tbaa !28, !noalias !38 + store i32 43, i32* %tmp20, align 4, !tbaa !23, !noalias !38 + %tmp21 = bitcast %struct.FUM* %l3_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp21) #5, !noalias !32 + %tmp22 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp22) #5 + ret void +} + +; CHECK-LABEL: @test02_aggloadstore +; CHECK-NOT: alloca +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !30) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !30) +; CHECK: %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %a_fum, i8* null, metadata !32, metadata !27) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %cp1.fca.0.[[GEP5:gep[0-9]+]] = getelementptr inbounds %struct.FUM, %struct.FUM* %a_fum, i32 0, i32 0 +; CHECK: %cp1.fca.0.load.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %cp1.fca.0.load, i8* null, i32** %cp1.fca.0.[[GEP5]], i64 0, metadata !27) +; CHECK: %cp1.fca.1.0.[[GEP6:gep[0-9]+]] = getelementptr inbounds %struct.FUM, %struct.FUM* %a_fum, i32 0, i32 1, i32 0 +; CHECK: %cp1.fca.1.0.load.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %cp1.fca.1.0.load, i8* null, i32** %cp1.fca.1.0.[[GEP6]], i64 0, metadata !27) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %2 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !35) +; CHECK: %3 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !35) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %cp2.fca.0.load.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %cp1.fca.0.extract, i8* %0, i32** null, i64 0, metadata !30) +; CHECK: %cp2.fca.1.0.load.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %cp1.fca.1.0.extract, i8* %1, i32** null, i64 4, metadata !30) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %tmp12 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %cp2.fca.{{.*}}.extract, i8* %2, i32** null, i64 0, metadata !35), !tbaa !17, !noalias !37 +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %4 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !38) +; CHECK: %5 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !38) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %cp3.fca.0.load.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %cp1.fca.0.extract, i8* %0, i32** null, i64 0, metadata !30) +; CHECK: %cp3.fca.1.0.load.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %cp1.fca.1.0.extract, i8* %1, i32** null, i64 4, metadata !30) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %tmp20 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{cp3|cp2}}.fca.1.0.extract, i8* %5, i32** null, i64 4, metadata !38), !tbaa !25, !noalias !40 +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: ret void + +; Function Attrs: nounwind +define dso_local void @test03_i64loadstore(%struct.FUM* %a_fum) #0 !noalias !41 { +entry: + %a_fum.addr = alloca %struct.FUM*, align 4 + %l_fum = alloca %struct.FUM, align 4 + %l2_fum = alloca %struct.FUM, align 4 + %l3_fum = alloca %struct.FUM, align 4 + store %struct.FUM* %a_fum, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !44 + %tmp0 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp0) #5, !noalias !44 + %tmp1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l_fum, i64 0, metadata !46), !noalias !44 + %tmp2 = load %struct.FUM*, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !44 + %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %tmp2, i8* null, metadata !13, metadata !41) + %tmp4 = bitcast %struct.FUM* %l_fum to i64* + %tmp5 = bitcast %struct.FUM* %tmp3 to i64* + %cp1 = load i64, i64* %tmp5, align 4 + store i64 %cp1, i64* %tmp4, align 4 + %tmp6 = bitcast %struct.FUM* %l2_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp6) #5, !noalias !47 + %tmp7 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l2_fum, i64 0, metadata !49), !noalias !47 + %tmp8 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %l_fum, i8* %tmp1, metadata !13, metadata !46) + %tmp9 = bitcast %struct.FUM* %l2_fum to i64* + %tmp10 = bitcast %struct.FUM* %tmp8 to i64* + %cp2 = load i64, i64* %tmp10, align 4 + store i64 %cp2, i64* %tmp9, align 4 + %p0 = getelementptr inbounds %struct.FUM, %struct.FUM* %l2_fum, i32 0, i32 0 + %tmp11 = load i32*, i32** %p0, align 4, !tbaa !20, !noalias !47 + %tmp12 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp11, i8* %tmp7, i32** %p0, i64 0, metadata !49), !tbaa !20, !noalias !47 + store i32 42, i32* %tmp12, align 4, !tbaa !23, !noalias !47 + %tmp13 = bitcast %struct.FUM* %l2_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp13) #5, !noalias !44 + %tmp14 = bitcast %struct.FUM* %l3_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp14) #5, !noalias !50 + %tmp15 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l3_fum, i64 0, metadata !52), !noalias !50 + %tmp16 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %l_fum, i8* %tmp1, metadata !13, metadata !46) + %tmp17 = bitcast %struct.FUM* %l3_fum to i64* + %tmp18 = bitcast %struct.FUM* %tmp16 to i64* + %cp3 = load i64, i64* %tmp18, align 4 + store i64 %cp3, i64* %tmp17, align 4 + %m1 = getelementptr inbounds %struct.FUM, %struct.FUM* %l3_fum, i32 0, i32 1 + %p = getelementptr inbounds %struct.FOO, %struct.FOO* %m1, i32 0, i32 0 + %tmp19 = load i32*, i32** %p, align 4, !tbaa !28, !noalias !50 + %tmp20 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp19, i8* %tmp15, i32** %p, i64 0, metadata !52), !tbaa !28, !noalias !50 + store i32 43, i32* %tmp20, align 4, !tbaa !23, !noalias !50 + %tmp21 = bitcast %struct.FUM* %l3_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp21) #5, !noalias !44 + %tmp22 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp22) #5 + ret void +} + +; CHECK-LABEL: @test03_i64loadstore +; CHECK-NOT: alloca +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !44) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !44) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %{{cp1[0-9]*}}.sroa_as_ptr.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{cp1[0-9]*}}.sroa_as_ptr, i8* null, i32** %2, i64 0, metadata !41) +; CHECK: %{{cp1[0-9]*}}.sroa_as_ptr.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{cp1[0-9]*}}.sroa_as_ptr, i8* null, i32** %3, i64 0, metadata !41) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %6 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !46) +; CHECK: %7 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !46) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK_S: %cp21.sroa_as_ptr.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %4, i8* %0, i32** null, i64 0, metadata !44) +; CHECK_S: %cp22.sroa_as_ptr.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %5, i8* %1, i32** null, i64 4, metadata !44) +; CHECK: %{{cp2[0-9]+}}.sroa_as_ptr.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %4, i8* %0, i32** null, i64 0, metadata !44) +; CHECK: %{{cp2[0-9]+}}.sroa_as_ptr.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %5, i8* %1, i32** null, i64 4, metadata !44) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %tmp12 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %8, i8* %6, i32** null, i64 0, metadata !46), !tbaa !17, !noalias !48 +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %10 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !49) +; CHECK: %11 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !49) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %{{cp3[0-9]*}}.sroa_as_ptr.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %4, i8* %0, i32** null, i64 0, metadata !44) +; CHECK: %{{cp3[0-9]*}}.sroa_as_ptr.noalias = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %5, i8* %1, i32** null, i64 4, metadata !44) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: %tmp20 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %13, i8* %11, i32** null, i64 4, metadata !49), !tbaa !25, !noalias !51 +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK-NOT: llvm.noalias.p +; CHECK-NOT: llvm.noalias.decl +; CHECK: ret void + + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { argmemonly nounwind } +attributes #3 = { nounwind readnone } +attributes #4 = { argmemonly nounwind speculatable } +attributes #5 = { nounwind } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"NumRegisterParameters", i32 0} +!1 = !{i32 1, !"wchar_size", i32 4} +!2 = !{!"clang version"} +!3 = !{!4} +!4 = distinct !{!4, !5, !"test01_memcpy: unknown scope"} +!5 = distinct !{!5, !"test01_memcpy"} +!6 = !{!7, !7, i64 0} +!7 = !{!"any pointer", !8, i64 0} +!8 = !{!"omnipotent char", !9, i64 0} +!9 = !{!"Simple C/C++ TBAA"} +!10 = !{!11, !4} +!11 = distinct !{!11, !5, !"test01_memcpy: l_fum"} +!12 = !{!11} +!13 = !{i64 8, i64 0, !14, i64 1} +!14 = !{i64 8, i64 0, i64 4, i64 1, i64 4, !15, i64 1} +!15 = !{i64 4, i64 0, i64 4, i64 1} +!16 = !{i64 0, i64 4, !6, i64 4, i64 4, !6} +!17 = !{!18, !11, !4} +!18 = distinct !{!18, !5, !"test01_memcpy: l2_fum"} +!19 = !{!18} +!20 = !{!21, !7, i64 0} +!21 = !{!"FUM", !7, i64 0, !22, i64 4} +!22 = !{!"FOO", !7, i64 0} +!23 = !{!24, !24, i64 0} +!24 = !{!"int", !8, i64 0} +!25 = !{!26, !11, !4} +!26 = distinct !{!26, !5, !"test01_memcpy: l3_fum"} +!27 = !{!26} +!28 = !{!21, !7, i64 4} +!29 = !{!30} +!30 = distinct !{!30, !31, !"test02_aggloadstore: unknown scope"} +!31 = distinct !{!31, !"test02_aggloadstore"} +!32 = !{!33, !30} +!33 = distinct !{!33, !31, !"test02_aggloadstore: l_fum"} +!34 = !{!33} +!35 = !{!36, !33, !30} +!36 = distinct !{!36, !31, !"test02_aggloadstore: l2_fum"} +!37 = !{!36} +!38 = !{!39, !33, !30} +!39 = distinct !{!39, !31, !"test02_aggloadstore: l3_fum"} +!40 = !{!39} +!41 = !{!42} +!42 = distinct !{!42, !43, !"test03_i64loadstore: unknown scope"} +!43 = distinct !{!43, !"test03_i64loadstore"} +!44 = !{!45, !42} +!45 = distinct !{!45, !43, !"test03_i64loadstore: l_fum"} +!46 = !{!45} +!47 = !{!48, !45, !42} +!48 = distinct !{!48, !43, !"test03_i64loadstore: l2_fum"} +!49 = !{!48} +!50 = !{!51, !45, !42} +!51 = distinct !{!51, !43, !"test03_i64loadstore: l3_fum"} +!52 = !{!51} + +; CHECK: !0 = !{i32 1, !"NumRegisterParameters", i32 0} +; CHECK: !1 = !{i32 1, !"wchar_size", i32 4} +; CHECK: !2 = !{!"clang version"} +; CHECK: !3 = !{!4} +; CHECK: !4 = distinct !{!4, !5, !"test01_memcpy: unknown scope"} +; CHECK: !5 = distinct !{!5, !"test01_memcpy"} +; CHECK: !6 = !{!7} +; CHECK: !7 = distinct !{!7, !5, !"test01_memcpy: l_fum"} +; CHECK: !8 = !{i64 0, i64 4, !9, i64 4, i64 4, !9} +; CHECK: !9 = !{!10, !10, i64 0} +; CHECK: !10 = !{!"any pointer", !11, i64 0} +; CHECK: !11 = !{!"omnipotent char", !12, i64 0} +; CHECK: !12 = !{!"Simple C/C++ TBAA"} +; CHECK: !13 = !{!7, !4} +; CHECK: !14 = !{i64 0, i64 4, !9} +; CHECK: !15 = !{!16} +; CHECK: !16 = distinct !{!16, !5, !"test01_memcpy: l2_fum"} +; CHECK: !17 = !{!18, !10, i64 0} +; CHECK: !18 = !{!"FUM", !10, i64 0, !19, i64 4} +; CHECK: !19 = !{!"FOO", !10, i64 0} +; CHECK: !20 = !{!16, !7, !4} +; CHECK: !21 = !{!22, !22, i64 0} +; CHECK: !22 = !{!"int", !11, i64 0} +; CHECK: !23 = !{!24} +; CHECK: !24 = distinct !{!24, !5, !"test01_memcpy: l3_fum"} +; CHECK: !25 = !{!18, !10, i64 4} +; CHECK: !26 = !{!24, !7, !4} +; CHECK: !27 = !{!28} +; CHECK: !28 = distinct !{!28, !29, !"test02_aggloadstore: unknown scope"} +; CHECK: !29 = distinct !{!29, !"test02_aggloadstore"} +; CHECK: !30 = !{!31} +; CHECK: !31 = distinct !{!31, !29, !"test02_aggloadstore: l_fum"} +; CHECK: !32 = !{i64 8, i64 0, !33, i64 1} +; CHECK: !33 = !{i64 8, i64 0, i64 4, i64 1, i64 4, !34, i64 1} +; CHECK: !34 = !{i64 4, i64 0, i64 4, i64 1} +; CHECK: !35 = !{!36} +; CHECK: !36 = distinct !{!36, !29, !"test02_aggloadstore: l2_fum"} +; CHECK: !37 = !{!36, !31, !28} +; CHECK: !38 = !{!39} +; CHECK: !39 = distinct !{!39, !29, !"test02_aggloadstore: l3_fum"} +; CHECK: !40 = !{!39, !31, !28} +; CHECK: !41 = !{!42} +; CHECK: !42 = distinct !{!42, !43, !"test03_i64loadstore: unknown scope"} +; CHECK: !43 = distinct !{!43, !"test03_i64loadstore"} +; CHECK: !44 = !{!45} +; CHECK: !45 = distinct !{!45, !43, !"test03_i64loadstore: l_fum"} +; CHECK: !46 = !{!47} +; CHECK: !47 = distinct !{!47, !43, !"test03_i64loadstore: l2_fum"} +; CHECK: !48 = !{!47, !45, !42} +; CHECK: !49 = !{!50} +; CHECK: !50 = distinct !{!50, !43, !"test03_i64loadstore: l3_fum"} +; CHECK: !51 = !{!50, !45, !42} Index: llvm/test/Transforms/SROA/noalias3.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/SROA/noalias3.ll @@ -0,0 +1,41 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -sroa -S | FileCheck %s +; RUN: opt < %s -passes=sroa -S | FileCheck %s + +; ModuleID = 'zzz_test.ll' +source_filename = "zzz_test.i" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: argmemonly nofree nosync nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #0 + +; Function Attrs: argmemonly nofree nosync nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #0 + +define i32 @main() local_unnamed_addr { +; CHECK-LABEL: @main( +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i32 undef +; CHECK: i.exit: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* undef, ptr_provenance i32* null, align 4, !tbaa [[TBAA0:![0-9]+]] +; CHECK-NEXT: ret i32 0 +; +entry: + %h.i = alloca [21 x i32], align 16 + %0 = bitcast [21 x i32]* %h.i to i8* + call void @llvm.lifetime.start.p0i8(i64 84, i8* %0) + ret i32 undef + +i.exit: ; No predecessors! + %arraydecay.i = getelementptr inbounds [21 x i32], [21 x i32]* %h.i, i64 0, i64 0 + %1 = load i32, i32* undef, ptr_provenance i32* %arraydecay.i, align 4, !tbaa !0 + ret i32 0 +} + +attributes #0 = { argmemonly nofree nosync nounwind willreturn } + +!0 = !{!1, !1, i64 0} +!1 = !{!"int", !2, i64 0} +!2 = !{!"omnipotent char", !3, i64 0} +!3 = !{!"Simple C/C++ TBAA"} Index: llvm/test/Transforms/SROA/noalias4.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/SROA/noalias4.ll @@ -0,0 +1,56 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -sroa -S | FileCheck %s +; RUN: opt < %s -passes=sroa -S | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.wobble.63 = type <{ %struct.blam.64, i32, [4 x i8] }> +%struct.blam.64 = type { i64 } + +; Function Attrs: argmemonly nofree nosync nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #0 + +define hidden void @test01(i1 %a0) local_unnamed_addr align 32 { +; CHECK-LABEL: @test01( +; CHECK-NEXT: bb0: +; CHECK-NEXT: br label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: br i1 [[A0:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: br label [[BB3]] +; CHECK: bb3: +; CHECK-NEXT: [[TMP26167:%.*]] = phi i64* [ null, [[BB2]] ], [ undef, [[BB1]] ] +; CHECK-NEXT: ret void +; +bb0: + %tmp73 = alloca %struct.wobble.63, align 8 + %tmp25701 = bitcast %struct.wobble.63* %tmp73 to i8* + call void @llvm.lifetime.start.p0i8(i64 16, i8* %tmp25701) + br label %bb1 + +bb1: ; preds = %bb25700 + br i1 %a0, label %bb2, label %bb3 + +bb2: ; preds = %bb26124 + %tmp26144 = call %struct.wobble.63* @llvm.provenance.noalias.p0s_struct.wobble.63s.p0i8.p0p0s_struct.wobble.63s.p0p0s_struct.wobble.63s.i64(%struct.wobble.63* nonnull %tmp73, i8* undef, %struct.wobble.63** null, %struct.wobble.63** undef, i64 0, metadata !1) + %tmp26145 = getelementptr %struct.wobble.63, %struct.wobble.63* %tmp26144, i64 0, i32 0, i32 0 + br label %bb3 + +bb3: ; preds = %bb26143, %bb26131 + %tmp26167 = phi i64* [ %tmp26145, %bb2 ], [ undef, %bb1 ] + ret void +} + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare %struct.wobble.63* @llvm.provenance.noalias.p0s_struct.wobble.63s.p0i8.p0p0s_struct.wobble.63s.p0p0s_struct.wobble.63s.i64(%struct.wobble.63*, i8*, %struct.wobble.63**, %struct.wobble.63**, i64, metadata) #1 + +attributes #0 = { argmemonly nofree nosync nounwind willreturn } +attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } + +!llvm.ident = !{!0 } + +!0 = !{!"clang"} +!1 = !{!2} +!2 = distinct !{!2, !3, !"test02: argument 0"} +!3 = distinct !{!3, !"test01"} Index: llvm/test/Transforms/SROA/noalias_copy_guard.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/SROA/noalias_copy_guard.ll @@ -0,0 +1,358 @@ +; using memcpy: +; RUN: sed < %s -e 's,;V1 , ,' | opt -sroa -S | FileCheck %s --check-prefixes=CHECK,CHECK_V1 +; RUN: sed < %s -e 's,;V1 , ,' | opt -passes=sroa -S | FileCheck %s --check-prefixes=CHECK,CHECK_V1 + +; using aggregate load/store: +; RUN: sed < %s -e 's,;V2 , ,' | opt -sroa -S | FileCheck %s --check-prefixes=CHECK,CHECK_V2 +; RUN: sed < %s -e 's,;V2 , ,' | opt -passes=sroa -S | FileCheck %s --check-prefixes=CHECK,CHECK_V2 + +; using i64 load/store: +; RUN: sed < %s -e 's,;V3 , ,' | opt -sroa -S | FileCheck %s --check-prefixes=CHECK,CHECK_V3 +; RUN: sed < %s -e 's,;V3 , ,' | opt -passes=sroa -S | FileCheck %s --check-prefixes=CHECK,CHECK_V3 + + +; Validate that SROA correctly deduces noalias pointers when removing: +; - llvm.mempcy +; - aggregate load/store +; - copying the struct through i64 + +; General form of each function is based on: +; ------ +; struct FOO { +; int* __restrict p; +; }; +; +; struct FUM { +; int* __restrict p0; +; struct FOO m1; +; }; +; +; void test01(struct FUM* a_fum) +; { +; struct FUM l_fum = *a_fum; +; *l_fum.p0 = 42; +; } +; +; void test02(struct FUM* a_fum) +; { +; struct FUM l_fum = *a_fum; +; *l_fum.m1.p = 43; +; } +; +; void test03(struct FUM* a_fum) +; { +; struct FUM l_fum = *a_fum; +; *l_fum.p0 = 42; +; *l_fum.m1.p = 43; +; } + + +; ModuleID = 'test3.c' +source_filename = "test3.c" +target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" +target triple = "i386-unknown-linux-gnu" + +%struct.FUM = type { i32*, %struct.FOO } +%struct.FOO = type { i32* } + +; Function Attrs: nounwind +define dso_local void @test01(%struct.FUM* %a_fum) #0 !noalias !3 { +entry: + %a_fum.addr = alloca %struct.FUM*, align 4 + %l_fum = alloca %struct.FUM, align 4 + store %struct.FUM* %a_fum, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !10 + %tmp0 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp0) #5, !noalias !10 + %tmp1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l_fum, i64 0, metadata !12), !noalias !10 + %tmp2 = load %struct.FUM*, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !10 + %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %tmp2, i8* null, metadata !13, metadata !3) + +;V1 %tmp4 = bitcast %struct.FUM* %l_fum to i8* +;V1 %tmp5 = bitcast %struct.FUM* %tmp3 to i8* +;V1 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %tmp4, i8* align 4 %tmp5, i32 8, i1 false), !tbaa.struct !16, !noalias !10 + +;V2 %cp1 = load %struct.FUM, %struct.FUM* %tmp3, align 4 +;V2 store %struct.FUM %cp1, %struct.FUM* %l_fum, align 4 + +;V3 %tmp4 = bitcast %struct.FUM* %l_fum to i64* +;V3 %tmp5 = bitcast %struct.FUM* %tmp3 to i64* +;V3 %cp1 = load i64, i64* %tmp5, align 4 +;V3 store i64 %cp1, i64* %tmp4, align 4 + + %p0 = getelementptr inbounds %struct.FUM, %struct.FUM* %l_fum, i32 0, i32 0 + %tmp6 = load i32*, i32** %p0, align 4, !tbaa !17, !noalias !10 + %tmp7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp6, i8* %tmp1, i32** %p0, i64 0, metadata !12), !tbaa !17, !noalias !10 + store i32 42, i32* %tmp7, align 4, !tbaa !20, !noalias !10 + %tmp8 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp8) #5 + ret void +} + +; CHECK-LABEL: test01 +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata !6) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata !6) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK_V2: %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %a_fum, i8* null, metadata !8, metadata !3) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK: %{{.*}} = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* null, i32** %{{.*}}, i64 0, metadata !3) +; CHECK: %{{.*}} = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* null, i32** %{{.*}}, i64 0, metadata !3) +; CHECK: %tmp7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* %0, i32** null, i64 0, metadata !6) +; CHECK: ret void + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg %tmp0, i8* nocapture %tmp1) #1 + +; Function Attrs: argmemonly nounwind +declare i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %tmp0, i64 %tmp1, metadata %tmp2) #2 + +; Function Attrs: nounwind readnone +declare %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %tmp0, i8* %tmp1, metadata %tmp2, metadata %tmp3) #3 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly %tmp0, i8* noalias nocapture readonly %tmp1, i32 %tmp2, i1 immarg %tmp3) #1 + +; Function Attrs: argmemonly nounwind speculatable +declare i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp0, i8* %tmp1, i32** %tmp2, i64 %tmp3, metadata %tmp4) #4 + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg %tmp0, i8* nocapture %tmp1) #1 + +; Function Attrs: nounwind +define dso_local void @test02(%struct.FUM* %a_fum) #0 !noalias !22 { +entry: + %a_fum.addr = alloca %struct.FUM*, align 4 + %l_fum = alloca %struct.FUM, align 4 + store %struct.FUM* %a_fum, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !25 + %tmp0 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp0) #5, !noalias !25 + %tmp1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l_fum, i64 0, metadata !27), !noalias !25 + %tmp2 = load %struct.FUM*, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !25 + %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %tmp2, i8* null, metadata !13, metadata !22) + +;V1 %tmp4 = bitcast %struct.FUM* %l_fum to i8* +;V1 %tmp5 = bitcast %struct.FUM* %tmp3 to i8* +;V1 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %tmp4, i8* align 4 %tmp5, i32 8, i1 false), !tbaa.struct !16, !noalias !25 + +;V2 %cp1 = load %struct.FUM, %struct.FUM* %tmp3, align 4 +;V2 store %struct.FUM %cp1, %struct.FUM* %l_fum, align 4 + +;V3 %tmp4 = bitcast %struct.FUM* %l_fum to i64* +;V3 %tmp5 = bitcast %struct.FUM* %tmp3 to i64* +;V3 %cp1 = load i64, i64* %tmp5, align 4 +;V3 store i64 %cp1, i64* %tmp4, align 4 + + %m1 = getelementptr inbounds %struct.FUM, %struct.FUM* %l_fum, i32 0, i32 1 + %p = getelementptr inbounds %struct.FOO, %struct.FOO* %m1, i32 0, i32 0 + %tmp6 = load i32*, i32** %p, align 4, !tbaa !28, !noalias !25 + %tmp7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp6, i8* %tmp1, i32** %p, i64 0, metadata !27), !tbaa !28, !noalias !25 + store i32 43, i32* %tmp7, align 4, !tbaa !20, !noalias !25 + %tmp8 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp8) #5 + ret void +} + +; CHECK-LABEL: test02 +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata ![[SCOPE2:[0-9]+]]) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata ![[SCOPE2]]) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK_V2: %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %a_fum, i8* null, metadata !{{[0-9]+}}, metadata !{{[0-9]+}}) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK: %{{.*}} = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* null, i32** %{{.*}}, i64 0, metadata ![[SCOPE2_OUT:[0-9]+]]) +; CHECK: %{{.*}} = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* null, i32** %{{.*}}, i64 0, metadata ![[SCOPE2_OUT]]) +; CHECK: %tmp7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* %1, i32** null, i64 4, metadata ![[SCOPE2]]) +; CHECK: ret void + +; Function Attrs: nounwind +define dso_local void @test03(%struct.FUM* %a_fum) #0 !noalias !29 { +entry: + %a_fum.addr = alloca %struct.FUM*, align 4 + %l_fum = alloca %struct.FUM, align 4 + store %struct.FUM* %a_fum, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !32 + %tmp0 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.start.p0i8(i64 8, i8* %tmp0) #5, !noalias !32 + %tmp1 = call i8* @llvm.noalias.decl.p0i8.p0s_struct.FUMs.i64(%struct.FUM* %l_fum, i64 0, metadata !34), !noalias !32 + %tmp2 = load %struct.FUM*, %struct.FUM** %a_fum.addr, align 4, !tbaa !6, !noalias !32 + %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %tmp2, i8* null, metadata !13, metadata !29) + +;V1 %tmp4 = bitcast %struct.FUM* %l_fum to i8* +;V1 %tmp5 = bitcast %struct.FUM* %tmp3 to i8* +;V1 call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %tmp4, i8* align 4 %tmp5, i32 8, i1 false), !tbaa.struct !16, !noalias !32 + +;V2 %cp1 = load %struct.FUM, %struct.FUM* %tmp3, align 4 +;V2 store %struct.FUM %cp1, %struct.FUM* %l_fum, align 4 + +;V3 %tmp4 = bitcast %struct.FUM* %l_fum to i64* +;V3 %tmp5 = bitcast %struct.FUM* %tmp3 to i64* +;V3 %cp1 = load i64, i64* %tmp5, align 4 +;V3 store i64 %cp1, i64* %tmp4, align 4 + + %p0 = getelementptr inbounds %struct.FUM, %struct.FUM* %l_fum, i32 0, i32 0 + %tmp6 = load i32*, i32** %p0, align 4, !tbaa !17, !noalias !32 + %tmp7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp6, i8* %tmp1, i32** %p0, i64 0, metadata !34), !tbaa !17, !noalias !32 + store i32 42, i32* %tmp7, align 4, !tbaa !20, !noalias !32 + %m1 = getelementptr inbounds %struct.FUM, %struct.FUM* %l_fum, i32 0, i32 1 + %p = getelementptr inbounds %struct.FOO, %struct.FOO* %m1, i32 0, i32 0 + %tmp8 = load i32*, i32** %p, align 4, !tbaa !28, !noalias !32 + %tmp9 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %tmp8, i8* %tmp1, i32** %p, i64 0, metadata !34), !tbaa !28, !noalias !32 + store i32 43, i32* %tmp9, align 4, !tbaa !20, !noalias !32 + %tmp10 = bitcast %struct.FUM* %l_fum to i8* + call void @llvm.lifetime.end.p0i8(i64 8, i8* %tmp10) #5 + ret void +} + +; CHECK-LABEL: test03 +; CHECK: %0 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 0, metadata ![[SCOPE3:[0-9]+]]) +; CHECK: %1 = call i8* @llvm.noalias.decl.p0i8.p0p0i32.i64(i32** null, i64 4, metadata ![[SCOPE3]]) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK_V2: %tmp3 = call %struct.FUM* @llvm.noalias.copy.guard.p0s_struct.FUMs.p0i8(%struct.FUM* %a_fum, i8* null, metadata !8, metadata !{{[0-9]+}}) +; CHECK-NOT: llvm.noalias.copy.guard +; CHECK: %{{.*}} = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* null, i32** %{{.*}}, i64 0, metadata ![[SCOPE3_OUT:[0-9]+]]) +; CHECK: %{{.*}} = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* null, i32** %{{.*}}, i64 0, metadata ![[SCOPE3_OUT]]) +; CHECK: %tmp7 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* %0, i32** null, i64 0, metadata ![[SCOPE3]]) +; CHECK: %tmp9 = call i32* @llvm.noalias.p0i32.p0i8.p0p0i32.i64(i32* %{{.*}}, i8* %1, i32** null, i64 4, metadata ![[SCOPE3]]) +; CHECK: ret void + +attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { argmemonly nounwind } +attributes #3 = { nounwind readnone } +attributes #4 = { argmemonly nounwind speculatable } +attributes #5 = { nounwind } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"NumRegisterParameters", i32 0} +!1 = !{i32 1, !"wchar_size", i32 4} +!2 = !{!"clang version"} +!3 = !{!4} +!4 = distinct !{!4, !5, !"test01: unknown scope"} +!5 = distinct !{!5, !"test01"} +!6 = !{!7, !7, i64 0} +!7 = !{!"any pointer", !8, i64 0} +!8 = !{!"omnipotent char", !9, i64 0} +!9 = !{!"Simple C/C++ TBAA"} +!10 = !{!11, !4} +!11 = distinct !{!11, !5, !"test01: l_fum"} +!12 = !{!11} +!13 = !{i64 8, i64 0, !14, i64 0} +!14 = !{i64 8, i64 0, i64 4, i64 1, i64 4, !15, i64 1} +!15 = !{i64 4, i64 0, i64 4, i64 1} +!16 = !{i64 0, i64 4, !6, i64 4, i64 4, !6} +!17 = !{!18, !7, i64 0} +!18 = !{!"FUM", !7, i64 0, !19, i64 4} +!19 = !{!"FOO", !7, i64 0} +!20 = !{!21, !21, i64 0} +!21 = !{!"int", !8, i64 0} +!22 = !{!23} +!23 = distinct !{!23, !24, !"test02: unknown scope"} +!24 = distinct !{!24, !"test02"} +!25 = !{!26, !23} +!26 = distinct !{!26, !24, !"test02: l_fum"} +!27 = !{!26} +!28 = !{!18, !7, i64 4} +!29 = !{!30} +!30 = distinct !{!30, !31, !"test03: unknown scope"} +!31 = distinct !{!31, !"test03"} +!32 = !{!33, !30} +!33 = distinct !{!33, !31, !"test03: l_fum"} +!34 = !{!33} + +; CHECK_V1: !0 = !{i32 1, !"NumRegisterParameters", i32 0} +; CHECK_V1: !1 = !{i32 1, !"wchar_size", i32 4} +; CHECK_V1: !2 = !{!"clang version"} +; CHECK_V1: !3 = !{!4} +; CHECK_V1: !4 = distinct !{!4, !5, !"test01: unknown scope"} +; CHECK_V1: !5 = distinct !{!5, !"test01"} +; CHECK_V1: !6 = !{!7} +; CHECK_V1: !7 = distinct !{!7, !5, !"test01: l_fum"} +; CHECK_V1: !8 = !{i64 0, i64 4, !9, i64 4, i64 4, !9} +; CHECK_V1: !9 = !{!10, !10, i64 0} +; CHECK_V1: !10 = !{!"any pointer", !11, i64 0} +; CHECK_V1: !11 = !{!"omnipotent char", !12, i64 0} +; CHECK_V1: !12 = !{!"Simple C/C++ TBAA"} +; CHECK_V1: !13 = !{!7, !4} +; CHECK_V1: !14 = !{i64 0, i64 4, !9} +; CHECK_V1: !15 = !{!16, !10, i64 0} +; CHECK_V1: !16 = !{!"FUM", !10, i64 0, !17, i64 4} +; CHECK_V1: !17 = !{!"FOO", !10, i64 0} +; CHECK_V1: !18 = !{!19, !19, i64 0} +; CHECK_V1: !19 = !{!"int", !11, i64 0} +; CHECK_V1: !20 = !{!21} +; CHECK_V1: !21 = distinct !{!21, !22, !"test02: unknown scope"} +; CHECK_V1: !22 = distinct !{!22, !"test02"} +; CHECK_V1: !23 = !{!24} +; CHECK_V1: !24 = distinct !{!24, !22, !"test02: l_fum"} +; CHECK_V1: !25 = !{!24, !21} +; CHECK_V1: !26 = !{!16, !10, i64 4} +; CHECK_V1: !27 = !{!28} +; CHECK_V1: !28 = distinct !{!28, !29, !"test03: unknown scope"} +; CHECK_V1: !29 = distinct !{!29, !"test03"} +; CHECK_V1: !30 = !{!31} +; CHECK_V1: !31 = distinct !{!31, !29, !"test03: l_fum"} +; CHECK_V1: !32 = !{!31, !28} + +; CHECK_V2: !0 = !{i32 1, !"NumRegisterParameters", i32 0} +; CHECK_V2: !1 = !{i32 1, !"wchar_size", i32 4} +; CHECK_V2: !2 = !{!"clang version"} +; CHECK_V2: !3 = !{!4} +; CHECK_V2: !4 = distinct !{!4, !5, !"test01: unknown scope"} +; CHECK_V2: !5 = distinct !{!5, !"test01"} +; CHECK_V2: !6 = !{!7} +; CHECK_V2: !7 = distinct !{!7, !5, !"test01: l_fum"} +; CHECK_V2: !8 = !{i64 8, i64 0, !9, i64 0} +; CHECK_V2: !9 = !{i64 8, i64 0, i64 4, i64 1, i64 4, !10, i64 1} +; CHECK_V2: !10 = !{i64 4, i64 0, i64 4, i64 1} +; CHECK_V2: !11 = !{!12, !13, i64 0} +; CHECK_V2: !12 = !{!"FUM", !13, i64 0, !16, i64 4} +; CHECK_V2: !13 = !{!"any pointer", !14, i64 0} +; CHECK_V2: !14 = !{!"omnipotent char", !15, i64 0} +; CHECK_V2: !15 = !{!"Simple C/C++ TBAA"} +; CHECK_V2: !16 = !{!"FOO", !13, i64 0} +; CHECK_V2: !17 = !{!7, !4} +; CHECK_V2: !18 = !{!19, !19, i64 0} +; CHECK_V2: !19 = !{!"int", !14, i64 0} +; CHECK_V2: !20 = !{!21} +; CHECK_V2: !21 = distinct !{!21, !22, !"test02: unknown scope"} +; CHECK_V2: !22 = distinct !{!22, !"test02"} +; CHECK_V2: !23 = !{!24} +; CHECK_V2: !24 = distinct !{!24, !22, !"test02: l_fum"} +; CHECK_V2: !25 = !{!12, !13, i64 4} +; CHECK_V2: !26 = !{!24, !21} +; CHECK_V2: !27 = !{!28} +; CHECK_V2: !28 = distinct !{!28, !29, !"test03: unknown scope"} +; CHECK_V2: !29 = distinct !{!29, !"test03"} +; CHECK_V2: !30 = !{!31} +; CHECK_V2: !31 = distinct !{!31, !29, !"test03: l_fum"} +; CHECK_V2: !32 = !{!31, !28} + +; CHECK_V3: !0 = !{i32 1, !"NumRegisterParameters", i32 0} +; CHECK_V3: !1 = !{i32 1, !"wchar_size", i32 4} +; CHECK_V3: !2 = !{!"clang version"} +; CHECK_V3: !3 = !{!4} +; CHECK_V3: !4 = distinct !{!4, !5, !"test01: unknown scope"} +; CHECK_V3: !5 = distinct !{!5, !"test01"} +; CHECK_V3: !6 = !{!7} +; CHECK_V3: !7 = distinct !{!7, !5, !"test01: l_fum"} +; CHECK_V3: !8 = !{!9, !10, i64 0} +; CHECK_V3: !9 = !{!"FUM", !10, i64 0, !13, i64 4} +; CHECK_V3: !10 = !{!"any pointer", !11, i64 0} +; CHECK_V3: !11 = !{!"omnipotent char", !12, i64 0} +; CHECK_V3: !12 = !{!"Simple C/C++ TBAA"} +; CHECK_V3: !13 = !{!"FOO", !10, i64 0} +; CHECK_V3: !14 = !{!7, !4} +; CHECK_V3: !15 = !{!16, !16, i64 0} +; CHECK_V3: !16 = !{!"int", !11, i64 0} +; CHECK_V3: !17 = !{!18} +; CHECK_V3: !18 = distinct !{!18, !19, !"test02: unknown scope"} +; CHECK_V3: !19 = distinct !{!19, !"test02"} +; CHECK_V3: !20 = !{!21} +; CHECK_V3: !21 = distinct !{!21, !19, !"test02: l_fum"} +; CHECK_V3: !22 = !{!9, !10, i64 4} +; CHECK_V3: !23 = !{!21, !18} +; CHECK_V3: !24 = !{!25} +; CHECK_V3: !25 = distinct !{!25, !26, !"test03: unknown scope"} +; CHECK_V3: !26 = distinct !{!26, !"test03"} +; CHECK_V3: !27 = !{!28} +; CHECK_V3: !28 = distinct !{!28, !26, !"test03: l_fum"} +; CHECK_V3: !29 = !{!28, !25} Index: llvm/test/Transforms/SROA/noalias_copy_guard2.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/SROA/noalias_copy_guard2.ll @@ -0,0 +1,72 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -sroa -S -o - %s | FileCheck %s +; RUN: opt -passes=sroa -S -o - %s | FileCheck %s + +source_filename = "zzz_test.i" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%union.e = type { %struct.a } +%struct.a = type { i32, i16, i64 } + +@g = external global %union.e, align 8 + +define i32 @h(%union.e* %p) { +; CHECK-LABEL: @h( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[I_SROA_0_0_P_I8_SROA_CAST:%.*]] = bitcast %union.e* [[P:%.*]] to { i32, i16 }** +; CHECK-NEXT: [[I_SROA_0_0_COPYLOAD:%.*]] = load { i32, i16 }*, { i32, i16 }** [[I_SROA_0_0_P_I8_SROA_CAST]], align 1, !tbaa.struct !0, !noalias !11 +; CHECK-NEXT: [[I_SROA_4_0_P_I8_SROA_IDX2:%.*]] = getelementptr inbounds [[UNION_E:%.*]], %union.e* [[P]], i64 0, i32 0, i32 2 +; CHECK-NEXT: [[I_SROA_4_0_COPYLOAD:%.*]] = load i64, i64* [[I_SROA_4_0_P_I8_SROA_IDX2]], align 1, !tbaa.struct !14, !noalias !11 +; CHECK-NEXT: [[TMP0:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0p0sl_i32i16s.i64({ i32, i16 }** null, i64 0, metadata [[META11:![0-9]+]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.noalias.decl.p0i8.p0i64.i64(i64* null, i64 8, metadata [[META11]]) +; CHECK-NEXT: [[TMP2:%.*]] = bitcast { i32, i16 }* [[I_SROA_0_0_COPYLOAD]] to i8* +; CHECK-NEXT: [[I_SROA_0_0_I_SROA_0_0_COPYLOAD1_NOALIAS:%.*]] = call i8* @llvm.noalias.p0i8.p0i8.p0p0sl_i32i16s.i64(i8* [[TMP2]], i8* [[TMP0]], { i32, i16 }** null, i64 0, metadata [[META11]]) +; CHECK-NEXT: [[I_SROA_0_0_COPYLOAD1_NOALIAS_CAST:%.*]] = bitcast i8* [[I_SROA_0_0_I_SROA_0_0_COPYLOAD1_NOALIAS]] to { i32, i16 }* +; CHECK-NEXT: store { i32, i16 }* [[I_SROA_0_0_COPYLOAD1_NOALIAS_CAST]], { i32, i16 }** bitcast (%union.e* @g to { i32, i16 }**), align 1, !tbaa.struct !0, !noalias !11 +; CHECK-NEXT: store i64 [[I_SROA_4_0_COPYLOAD]], i64* getelementptr inbounds ([[UNION_E]], %union.e* @g, i64 0, i32 0, i32 2), align 1, !tbaa.struct !14, !noalias !11 +; CHECK-NEXT: ret i32 undef +; +entry: + %retval = alloca i32, align 4 + %i = alloca %union.e, align 8 + %i.i8 = bitcast %union.e* %i to i8* + %p.i8 = bitcast %union.e* %p to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %i.i8, i8* %p.i8, i64 16, i1 false), !tbaa.struct !4, !noalias !0 + %0 = call i8* @llvm.noalias.decl.p0i8.p0s_union.es.i64(%union.e* %i, i64 0, metadata !0), !noalias !0 + %1 = call %union.e* @llvm.noalias.copy.guard.p0s_union.es.p0i8(%union.e* %i, i8* %0, metadata !3, metadata !0) + %2 = bitcast %union.e* %1 to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (%union.e* @g to i8*), i8* %2, i64 16, i1 false), !tbaa.struct !4, !noalias !0 + %3 = load i32, i32* %retval, align 4 + ret i32 %3 +} + +; Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn +declare i8* @llvm.noalias.decl.p0i8.p0s_union.es.i64(%union.e*, i64, metadata) #1 + +; Function Attrs: nofree nosync nounwind readnone willreturn +declare %union.e* @llvm.noalias.copy.guard.p0s_union.es.p0i8(%union.e*, i8*, metadata, metadata) #2 + +; Function Attrs: argmemonly nofree nounwind willreturn +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg) #3 + +attributes #0 = { argmemonly nofree nosync nounwind willreturn } +attributes #1 = { inaccessiblememonly nofree nosync nounwind willreturn } +attributes #2 = { nofree nosync nounwind readnone willreturn } +attributes #3 = { argmemonly nofree nounwind willreturn } + +!0 = !{!1} +!1 = distinct !{!1, !2, !"h: i"} +!2 = distinct !{!2, !"h"} +!3 = !{i64 16, i64 0, i64 8, i64 1} +!4 = !{i64 0, i64 4, !5, i64 4, i64 2, !9, i64 8, i64 8, !11, i64 0, i64 8, !13} +!5 = !{!6, !6, i64 0} +!6 = !{!"int", !7, i64 0} +!7 = !{!"omnipotent char", !8, i64 0} +!8 = !{!"Simple C/C++ TBAA"} +!9 = !{!10, !10, i64 0} +!10 = !{!"short", !7, i64 0} +!11 = !{!12, !12, i64 0} +!12 = !{!"long", !7, i64 0} +!13 = !{!14, !14, i64 0} +!14 = !{!"any pointer", !7, i64 0} Index: llvm/tools/llvm-c-test/echo.cpp =================================================================== --- llvm/tools/llvm-c-test/echo.cpp +++ llvm/tools/llvm-c-test/echo.cpp @@ -348,6 +348,12 @@ return LLVMGetUndef(TypeCloner(M).Clone(Cst)); } + // Try unknown_provenance + if (LLVMIsUnknownProvenance(Cst)) { + check_value_kind(Cst, LLVMUnknownProvenanceValueKind); + return LLVMGetUnknownProvenance(TypeCloner(M).Clone(Cst)); + } + // Try poison if (LLVMIsPoison(Cst)) { check_value_kind(Cst, LLVMPoisonValueValueKind); Index: llvm/unittests/IR/IRBuilderTest.cpp =================================================================== --- llvm/unittests/IR/IRBuilderTest.cpp +++ llvm/unittests/IR/IRBuilderTest.cpp @@ -12,6 +12,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsAArch64.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" @@ -418,6 +419,212 @@ EXPECT_FALSE(verifyModule(*M)); } +TEST_F(IRBuilderTest, NoAlias) { + IRBuilder<> Builder(BB); + AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty()); + + AllocaInst *VarP = Builder.CreateAlloca(Builder.getInt8PtrTy()); + Builder.CreateStore(Var1, VarP); + + MDBuilder MDB(BB->getContext()); + MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain("Test Domain"); + MDNode *AScope = MDB.createAnonymousAliasScope(NewDomain, "Test Scope"); + + CallInst *NAD = + cast(Builder.CreateNoAliasDeclaration(VarP, AScope)); + Value *Pointer = Builder.CreateLoad(Builder.getInt8PtrTy(), VarP); + CallInst *NAP = + cast(Builder.CreateNoAliasPointer(Pointer, NAD, VarP, AScope)); + + // llvm.noalias.decl + EXPECT_EQ(NAD->getArgOperand(Intrinsic::NoAliasDeclAllocaArg), VarP); + EXPECT_EQ( + cast(NAD->getArgOperand(Intrinsic::NoAliasDeclObjIdArg)) + ->getZExtValue(), + 0ull); + EXPECT_EQ( + cast(NAD->getArgOperand(Intrinsic::NoAliasDeclScopeArg)) + ->getMetadata(), + AScope); + + IntrinsicInst *II_NAD = dyn_cast(NAD); + ASSERT_TRUE(II_NAD != nullptr); + EXPECT_EQ(II_NAD->getIntrinsicID(), Intrinsic::noalias_decl); + + EXPECT_TRUE(NAD->onlyAccessesInaccessibleMemory()); + EXPECT_TRUE(NAD->doesNotThrow()); + + // llvm.noalias + EXPECT_EQ(NAP->getArgOperand(0), Pointer); + EXPECT_EQ(NAP->getArgOperand(Intrinsic::NoAliasNoAliasDeclArg), NAD); + EXPECT_EQ(NAP->getArgOperand(Intrinsic::NoAliasIdentifyPArg), VarP); + EXPECT_EQ( + cast(NAP->getArgOperand(Intrinsic::NoAliasScopeArg)) + ->getMetadata(), + AScope); + EXPECT_EQ( + cast(NAP->getArgOperand(Intrinsic::NoAliasIdentifyPObjIdArg)) + ->getZExtValue(), + 0ull); // default object id is 0 + + IntrinsicInst *II_NAP = dyn_cast(NAP); + ASSERT_TRUE(II_NAP != nullptr); + EXPECT_EQ(II_NAP->getIntrinsicID(), Intrinsic::noalias); + + EXPECT_TRUE(NAP->onlyAccessesArgMemory()); + EXPECT_TRUE(NAP->doesNotThrow()); +} + +TEST_F(IRBuilderTest, ProvenanceNoAliasAndArgGuard) { + IRBuilder<> Builder(BB); + AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty()); + + AllocaInst *VarP = Builder.CreateAlloca(Builder.getInt8PtrTy()); + Builder.CreateStore(Var1, VarP); + + MDBuilder MDB(BB->getContext()); + MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain("Test Domain"); + MDNode *AScope = MDB.createAnonymousAliasScope(NewDomain, "Test Scope"); + + CallInst *NAD = + cast(Builder.CreateNoAliasDeclaration(VarP, AScope)); + Value *Pointer = Builder.CreateLoad(Builder.getInt8PtrTy(), VarP); + CallInst *SNAP = cast(Builder.CreateProvenanceNoAliasPlain( + Pointer, NAD, VarP, llvm::ConstantPointerNull::get(VarP->getType()), + NAD->getArgOperand(Intrinsic::NoAliasDeclObjIdArg), AScope)); + + CallInst *NAG = cast(Builder.CreateNoAliasArgGuard(Pointer, SNAP)); + + // create load on Pointer, with SNAP provenance + + // llvm.provenance.noalias + EXPECT_EQ(SNAP->getArgOperand(0), Pointer); + EXPECT_EQ(SNAP->getArgOperand(Intrinsic::ProvenanceNoAliasNoAliasDeclArg), + NAD); + EXPECT_EQ(SNAP->getArgOperand(Intrinsic::ProvenanceNoAliasIdentifyPArg), + VarP); + EXPECT_EQ(cast( + SNAP->getArgOperand(Intrinsic::ProvenanceNoAliasScopeArg)) + ->getMetadata(), + AScope); + ASSERT_TRUE(cast( + SNAP->getArgOperand(Intrinsic::ProvenanceNoAliasIdentifyPProvenanceArg))); + EXPECT_EQ( + cast( + SNAP->getArgOperand(Intrinsic::ProvenanceNoAliasIdentifyPObjIdArg)) + ->getZExtValue(), + 0ull); // default object id is 0 + + IntrinsicInst *II_SNAP = dyn_cast(SNAP); + ASSERT_TRUE(II_SNAP != nullptr); + EXPECT_EQ(II_SNAP->getIntrinsicID(), Intrinsic::provenance_noalias); + + EXPECT_TRUE(SNAP->doesNotAccessMemory()); + EXPECT_TRUE(SNAP->doesNotThrow()); + + // llvm.noalias.arg.guard + EXPECT_EQ(NAG->getArgOperand(0), Pointer); + EXPECT_EQ(NAG->getArgOperand(1), SNAP); + + EXPECT_TRUE(NAG->doesNotAccessMemory()); + EXPECT_TRUE(NAG->doesNotThrow()); +} + +TEST_F(IRBuilderTest, NoAliasCopyGuard) { + // // roughly equivalent code for: + // struct FOO { char* __reststrict p; } + // char copy_restrict(struct FOO* p) { + // struct FOO local=*p; // Introduces llvm.noalias.copy.guard + // return *local.p; // NOTE: this part is omitted + // } + + IRBuilder<> Builder(BB); + StructType *ST = + StructType::create(BB->getContext(), {Builder.getInt8PtrTy()}); + + // pointer to incoming struct + AllocaInst *VarIn = Builder.CreateAlloca(ST->getPointerTo()); + + // local struct + AllocaInst *Var1 = Builder.CreateAlloca(ST); + // pointer to local struct + AllocaInst *VarP = Builder.CreateAlloca(ST->getPointerTo()); + Builder.CreateStore(Var1, VarP); + + MDBuilder MDB(BB->getContext()); + MDNode *NewDomain = MDB.createAnonymousAliasScopeDomain("Test Domain"); + MDNode *AScope = MDB.createAnonymousAliasScope(NewDomain, "Test Scope"); + + CallInst *NAD = + cast(Builder.CreateNoAliasDeclaration(VarP, AScope)); + (void)NAD; // not used as we don't do the 'return *local.p' here + + auto *SrcPointer = Builder.CreateLoad(ST->getPointerTo(), VarIn); + + auto Int8PtrNull = ConstantPointerNull::get(Builder.getInt8PtrTy()); + auto *PassThrough = Builder.CreateNoAliasCopyGuard( + SrcPointer, + Int8PtrNull, // out-of-function __restrict declaration + nullptr, // no restrict offsets + AScope); + EXPECT_EQ(PassThrough, SrcPointer); + + MDBuilder::NoAliasOffsetsField F(0, 8, 1); + MDNode *NAO = MDB.createNoAliasOffsets(8, {F}); + CallInst *GP = cast(Builder.CreateNoAliasCopyGuard( + SrcPointer, + Int8PtrNull, // out-of-function __restrict declaration + NAO, AScope)); + auto *Copy = Builder.CreateMemCpy( + Var1, Align(4), GP, Align(4), + BB->getParent()->getParent()->getDataLayout().getTypeStoreSize(ST)); + (void)Copy; + + // llvm.noalias.copy.guard + EXPECT_EQ(GP->getArgOperand(Intrinsic::NoAliasCopyGuardIdentifyPBaseObject), + SrcPointer); + EXPECT_EQ(GP->getArgOperand(Intrinsic::NoAliasCopyGuardNoAliasDeclArg), + Int8PtrNull); + + // hmm. how to easily check that we are pointing to a { { -1, 0 } } array ? + EXPECT_EQ(cast( + GP->getArgOperand(Intrinsic::NoAliasCopyGuardIndicesArg)) + ->getMetadata(), + NAO); + EXPECT_EQ(cast( + GP->getArgOperand(Intrinsic::NoAliasCopyGuardScopeArg)) + ->getMetadata(), + AScope); + + EXPECT_TRUE(GP->doesNotAccessMemory()); + EXPECT_TRUE(GP->doesNotThrow()); +} + +TEST_F(IRBuilderTest, Provenance) { + IRBuilder<> Builder(BB); + + auto *L = Builder.CreateLoad(GV->getValueType(), GV); + EXPECT_TRUE(!L->hasNoaliasProvenanceOperand()); + + auto *S = Builder.CreateStore(L, GV); + EXPECT_TRUE(!S->hasNoaliasProvenanceOperand()); + + L->setNoaliasProvenanceOperand(GV); + EXPECT_TRUE(L->hasNoaliasProvenanceOperand()); + + S->setNoaliasProvenanceOperand(GV); + EXPECT_TRUE(S->hasNoaliasProvenanceOperand()); + + EXPECT_EQ(L->getNoaliasProvenanceOperand(), GV); + EXPECT_EQ(S->getNoaliasProvenanceOperand(), GV); + + L->removeNoaliasProvenanceOperand(); + EXPECT_TRUE(!L->hasNoaliasProvenanceOperand()); + + S->removeNoaliasProvenanceOperand(); + EXPECT_TRUE(!S->hasNoaliasProvenanceOperand()); +} + TEST_F(IRBuilderTest, Lifetime) { IRBuilder<> Builder(BB); AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());