diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b02ac467cd3a2..f6d5c346021d6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -660,6 +660,8 @@ Improvements to Clang's diagnostics - Don't emit bogus dangling diagnostics when ``[[gsl::Owner]]`` and `[[clang::lifetimebound]]` are used together (#GH108272). +- Don't emit bogus dignostic about an undefined behavior on ``reinterpret_cast`` for non-instantiated template functions without sufficient knowledge whether it can actually lead to undefined behavior for ``T`` (#GH109430). + - The ``-Wreturn-stack-address`` warning now also warns about addresses of local variables passed to function calls using the ``[[clang::musttail]]`` attribute. @@ -860,7 +862,7 @@ Bug Fixes to C++ Support module imports in those situations. (#GH60336) - Fix init-capture packs having a size of one before being instantiated. (#GH63677) - Clang now preserves the unexpanded flag in a lambda transform used for pack expansion. (#GH56852), (#GH85667), - (#GH99877). + (#GH99877), (#GH122417). - Fixed a bug when diagnosing ambiguous explicit specializations of constrained member functions. - Fixed an assertion failure when selecting a function from an overload set that includes a specialization of a conversion function template. diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index 58fa64c80a16f..176a2a8d2a35e 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -898,7 +898,8 @@ class Sema; ConversionFixItGenerator Fix; /// Viable - True to indicate that this overload candidate is viable. - bool Viable : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned Viable : 1; /// Whether this candidate is the best viable function, or tied for being /// the best viable function. @@ -907,12 +908,14 @@ class Sema; /// was part of the ambiguity kernel: the minimal non-empty set of viable /// candidates such that all elements of the ambiguity kernel are better /// than all viable candidates not in the ambiguity kernel. - bool Best : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned Best : 1; /// IsSurrogate - True to indicate that this candidate is a /// surrogate for a conversion to a function pointer or reference /// (C++ [over.call.object]). - bool IsSurrogate : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned IsSurrogate : 1; /// IgnoreObjectArgument - True to indicate that the first /// argument's conversion, which for this function represents the @@ -921,12 +924,15 @@ class Sema; /// implicit object argument is just a placeholder) or a /// non-static member function when the call doesn't have an /// object argument. - bool IgnoreObjectArgument : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned IgnoreObjectArgument : 1; - bool TookAddressOfOverload : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned TookAddressOfOverload : 1; /// True if the candidate was found using ADL. - CallExpr::ADLCallKind IsADLCandidate : 1; + LLVM_PREFERRED_TYPE(CallExpr::ADLCallKind) + unsigned IsADLCandidate : 1; /// Whether this is a rewritten candidate, and if so, of what kind? LLVM_PREFERRED_TYPE(OverloadCandidateRewriteKind) @@ -999,7 +1005,8 @@ class Sema; friend class OverloadCandidateSet; OverloadCandidate() : IsSurrogate(false), IgnoreObjectArgument(false), - TookAddressOfOverload(false), IsADLCandidate(CallExpr::NotADL), + TookAddressOfOverload(false), + IsADLCandidate(llvm::to_underlying(CallExpr::NotADL)), RewriteKind(CRK_None) {} }; diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index cb0ce886f6680..c765ebf5d618e 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -321,7 +321,7 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, if (Ptr.isDynamic()) { S.FFDiag(Src, diag::note_constexpr_access_deleted_object) << AK; - } else { + } else if (!S.checkingPotentialConstantExpression()) { bool IsTemp = Ptr.isTemporary(); S.FFDiag(Src, diag::note_constexpr_lifetime_ended, 1) << AK << !IsTemp; @@ -416,9 +416,11 @@ bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK) { if (!Ptr.isOnePastEnd()) return true; - const SourceInfo &Loc = S.Current->getSource(OpPC); - S.FFDiag(Loc, diag::note_constexpr_access_past_end) - << AK << S.Current->getRange(OpPC); + if (S.getLangOpts().CPlusPlus) { + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.FFDiag(Loc, diag::note_constexpr_access_past_end) + << AK << S.Current->getRange(OpPC); + } return false; } @@ -538,7 +540,7 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, return true; if (const auto *VD = Ptr.getDeclDesc()->asVarDecl(); - VD && VD->hasGlobalStorage()) { + VD && (VD->isConstexpr() || VD->hasGlobalStorage())) { const SourceInfo &Loc = S.Current->getSource(OpPC); if (VD->getAnyInitializer()) { S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD; diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index f98857f852b5a..54bc52fa2ac40 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -2094,6 +2094,10 @@ void Sema::CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, } } + if (SrcTy->isDependentType() || DestTy->isDependentType()) { + return; + } + Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range; } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 34c287926b1d7..7e8811b5274ef 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -6977,7 +6977,7 @@ void Sema::AddOverloadCandidate( Candidate.Viable = true; Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Function, PO); - Candidate.IsADLCandidate = IsADLCandidate; + Candidate.IsADLCandidate = llvm::to_underlying(IsADLCandidate); Candidate.ExplicitCallArguments = Args.size(); // Explicit functions are not actually candidates at all if we're not @@ -7832,7 +7832,7 @@ void Sema::AddTemplateOverloadCandidate( Candidate.RewriteKind = CandidateSet.getRewriteInfo().getRewriteKind(Candidate.Function, PO); Candidate.IsSurrogate = false; - Candidate.IsADLCandidate = IsADLCandidate; + Candidate.IsADLCandidate = llvm::to_underlying(IsADLCandidate); // Ignore the object argument if there is one, since we don't have an object // type. Candidate.IgnoreObjectArgument = @@ -14082,7 +14082,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, return ExprError(); return SemaRef.BuildResolvedCallExpr( Res.get(), FDecl, LParenLoc, Args, RParenLoc, ExecConfig, - /*IsExecConfig=*/false, (*Best)->IsADLCandidate); + /*IsExecConfig=*/false, + static_cast((*Best)->IsADLCandidate)); } case OR_No_Viable_Function: { @@ -14156,7 +14157,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, return ExprError(); return SemaRef.BuildResolvedCallExpr( Res.get(), FDecl, LParenLoc, Args, RParenLoc, ExecConfig, - /*IsExecConfig=*/false, (*Best)->IsADLCandidate); + /*IsExecConfig=*/false, + static_cast((*Best)->IsADLCandidate)); } } @@ -14438,7 +14440,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Args[0] = Input; CallExpr *TheCall = CXXOperatorCallExpr::Create( Context, Op, FnExpr.get(), ArgsArray, ResultTy, VK, OpLoc, - CurFPFeatureOverrides(), Best->IsADLCandidate); + CurFPFeatureOverrides(), + static_cast(Best->IsADLCandidate)); if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl)) return ExprError(); @@ -14833,7 +14836,8 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // members; CodeGen should take care not to emit the this pointer. TheCall = CXXOperatorCallExpr::Create( Context, ChosenOp, FnExpr.get(), Args, ResultTy, VK, OpLoc, - CurFPFeatureOverrides(), Best->IsADLCandidate); + CurFPFeatureOverrides(), + static_cast(Best->IsADLCandidate)); if (const auto *Method = dyn_cast(FnDecl); Method && Method->isImplicitObjectMemberFunction()) { diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 4fae2ccb5f6d0..7dc88a1ae23b9 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -8499,7 +8499,7 @@ TreeTransform::TransformDeclStmt(DeclStmt *S) { getSema() .getASTContext() .getTypeDeclType(TD) - .getCanonicalType() + .getSingleStepDesugaredType(getSema().getASTContext()) ->containsUnexpandedParameterPack(); if (auto *VD = dyn_cast(Transformed)) diff --git a/clang/test/AST/ByteCode/c23.c b/clang/test/AST/ByteCode/c23.c index 5154d57f6cb9e..0e9851aa2ad3a 100644 --- a/clang/test/AST/ByteCode/c23.c +++ b/clang/test/AST/ByteCode/c23.c @@ -49,3 +49,11 @@ static_assert(arg1[1] == 254); static_assert(arg1[2] == 186); static_assert(arg1[3] == 190); #endif + +void ghissue109095() { + constexpr char c[] = { 'a' }; + constexpr int i = c[1]; // both-error {{constexpr variable 'i' must be initialized by a constant expression}}\ + // both-note {{declared here}} + _Static_assert(i == c[0]); // both-error {{static assertion expression is not an integral constant expression}}\ + // both-note {{initializer of 'i' is not a constant expression}} +} diff --git a/clang/test/AST/ByteCode/lifetimes.cpp b/clang/test/AST/ByteCode/lifetimes.cpp index 9a99485c4a40b..43039d0c766e9 100644 --- a/clang/test/AST/ByteCode/lifetimes.cpp +++ b/clang/test/AST/ByteCode/lifetimes.cpp @@ -7,15 +7,15 @@ struct Foo { int a; }; -constexpr int dead1() { // expected-error {{never produces a constant expression}} +constexpr int dead1() { Foo *F2 = nullptr; { - Foo F{12}; // expected-note 2{{declared here}} + Foo F{12}; // expected-note {{declared here}} F2 = &F; } // Ends lifetime of F. - return F2->a; // expected-note 2{{read of variable whose lifetime has ended}} \ + return F2->a; // expected-note {{read of variable whose lifetime has ended}} \ // ref-note {{read of object outside its lifetime is not allowed in a constant expression}} } static_assert(dead1() == 1, ""); // both-error {{not an integral constant expression}} \ diff --git a/clang/test/AST/ByteCode/literals.cpp b/clang/test/AST/ByteCode/literals.cpp index fdf1a6820e446..b75ca2b19a969 100644 --- a/clang/test/AST/ByteCode/literals.cpp +++ b/clang/test/AST/ByteCode/literals.cpp @@ -1315,3 +1315,12 @@ namespace { } } #endif + +void localConstexpr() { + constexpr int a = 1/0; // both-error {{must be initialized by a constant expression}} \ + // both-note {{division by zero}} \ + // both-warning {{division by zero is undefined}} \ + // both-note {{declared here}} + static_assert(a == 0, ""); // both-error {{not an integral constant expression}} \ + // both-note {{initializer of 'a' is not a constant expression}} +} diff --git a/clang/test/CodeGen/X86/ms-x86-intrinsics.c b/clang/test/CodeGen/X86/ms-x86-intrinsics.c index 94a1b372974b3..34cf690e6d5da 100644 --- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c +++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c @@ -171,7 +171,7 @@ __int64 test_mul128(__int64 Multiplier, __int64 *HighProduct) { return _mul128(Multiplier, Multiplicand, HighProduct); } -// CHECK-X64-LABEL: define dso_local i64 @test_mul128(i64 noundef %Multiplier, i64 noundef %Multiplicand, ptr{{[a-z_ ]*}} initializes((0, 8)) %HighProduct) +// CHECK-X64-LABEL: define dso_local i64 @test_mul128(i64 noundef %Multiplier, i64 noundef %Multiplicand, ptr{{.*}} initializes((0, 8)) %HighProduct) // CHECK-X64: = sext i64 %Multiplier to i128 // CHECK-X64: = sext i64 %Multiplicand to i128 // CHECK-X64: = mul nsw i128 % @@ -183,7 +183,7 @@ unsigned __int64 test_umul128(unsigned __int64 Multiplier, unsigned __int64 *HighProduct) { return _umul128(Multiplier, Multiplicand, HighProduct); } -// CHECK-X64-LABEL: define dso_local i64 @test_umul128(i64 noundef %Multiplier, i64 noundef %Multiplicand, ptr{{[a-z_ ]*}} initializes((0, 8)) %HighProduct) +// CHECK-X64-LABEL: define dso_local i64 @test_umul128(i64 noundef %Multiplier, i64 noundef %Multiplicand, ptr{{.*}} initializes((0, 8)) %HighProduct) // CHECK-X64: = zext i64 %Multiplier to i128 // CHECK-X64: = zext i64 %Multiplicand to i128 // CHECK-X64: = mul nuw i128 % diff --git a/clang/test/CodeGen/attr-counted-by-pr110385.c b/clang/test/CodeGen/attr-counted-by-pr110385.c index c2ff032334fe2..f211610c3173b 100644 --- a/clang/test/CodeGen/attr-counted-by-pr110385.c +++ b/clang/test/CodeGen/attr-counted-by-pr110385.c @@ -31,11 +31,11 @@ void init(void * __attribute__((pass_dynamic_object_size(0)))); // CHECK-NEXT: [[GROWABLE:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[GROWABLE]], align 8, !tbaa [[TBAA2:![0-9]+]] // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 12 -// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8 -// CHECK-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// CHECK-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8 +// CHECK-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 // CHECK-NEXT: [[TMP2:%.*]] = shl nsw i64 [[TMP1]], 1 -// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 +// CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1 // CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 0 // CHECK-NEXT: tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef [[TMP4]]) #[[ATTR2:[0-9]+]] // CHECK-NEXT: ret void @@ -48,11 +48,11 @@ void test1(struct bucket *foo) { // CHECK-SAME: ptr noundef [[FOO:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 16 -// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 12 -// CHECK-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// CHECK-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 12 +// CHECK-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 // CHECK-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 1 -// CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 +// CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1 // CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 // CHECK-NEXT: tail call void @init(ptr noundef nonnull [[ARRAY]], i64 noundef [[TMP3]]) #[[ATTR2]] // CHECK-NEXT: ret void @@ -60,3 +60,12 @@ void test1(struct bucket *foo) { void test2(struct bucket2 *foo) { init(foo->growable.array); } +//. +// CHECK: [[TBAA2]] = !{[[META3:![0-9]+]], [[META7:![0-9]+]], i64 8} +// CHECK: [[META3]] = !{!"bucket", [[META4:![0-9]+]], i64 0, [[META7]], i64 8, [[META4]], i64 16} +// CHECK: [[META4]] = !{!"int", [[META5:![0-9]+]], i64 0} +// CHECK: [[META5]] = !{!"omnipotent char", [[META6:![0-9]+]], i64 0} +// CHECK: [[META6]] = !{!"Simple C/C++ TBAA"} +// CHECK: [[META7]] = !{!"p1 _ZTS8variable", [[META8:![0-9]+]], i64 0} +// CHECK: [[META8]] = !{!"any pointer", [[META5]], i64 0} +//. diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c index 6b3cad5708835..1066e2e74160a 100644 --- a/clang/test/CodeGen/attr-counted-by.c +++ b/clang/test/CodeGen/attr-counted-by.c @@ -108,9 +108,9 @@ void test1(struct annotated *p, int index, int val) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[INDEX]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: @@ -119,7 +119,7 @@ void test1(struct annotated *p, int index, int val) { // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP2]], 2 // SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret void @@ -127,9 +127,9 @@ void test1(struct annotated *p, int index, int val) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP0]], 2 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] @@ -159,22 +159,22 @@ void test2(struct annotated *p, size_t index) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1 // SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 // SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]] // @@ -266,19 +266,19 @@ size_t test3_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT4:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: // SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont4: -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[COUNTED_BY_LOAD]], 2 // SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 244 // SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 252 // SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP2]], i32 [[TMP5]], i32 0 @@ -292,16 +292,16 @@ size_t test3_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM12]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont19: -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], 3 +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], 3 // SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = add i32 [[TMP3]], 240 // SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 252 // SANITIZE-WITH-ATTR-NEXT: [[CONV8:%.*]] = select i1 [[TMP7]], i32 [[TMP9]], i32 0 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM12]] // SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV8]], ptr [[ARRAYIDX17]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD21:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD21:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[ADD27:%.*]] = add nsw i32 [[INDEX]], 2 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM28:%.*]] = sext i32 [[ADD27]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD21]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = zext i32 [[COUNTED_BY_LOAD21]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp ult i64 [[IDXPROM28]], [[TMP10]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT35:%.*]], label [[HANDLER_OUT_OF_BOUNDS31:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds31: @@ -310,7 +310,7 @@ size_t test3_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR: cont35: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM28]] // SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[FAM_IDX]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD21]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = sext i32 [[COUNTED_BY_LOAD21]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = sext i32 [[FAM_IDX]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = sub nsw i64 [[TMP13]], [[TMP14]] // SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = icmp sgt i64 [[TMP15]], -1 @@ -325,29 +325,29 @@ size_t test3_bdos(struct annotated *p) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[COUNTED_BY_LOAD]], 2 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 244 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], 2 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i32 [[TMP1]], 252 // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD3:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD3]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD3:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = shl i32 [[COUNTED_BY_LOAD3]], 2 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], 240 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD3]], 3 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD3]], 3 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = and i32 [[TMP5]], 252 // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV5:%.*]] = select i1 [[TMP6]], i32 [[TMP7]], i32 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM7:%.*]] = sext i32 [[ADD]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM7]] // NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV5]], ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD10:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD10]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD10:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = sext i32 [[COUNTED_BY_LOAD10]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = sext i32 [[FAM_IDX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = sub nsw i64 [[TMP8]], [[TMP9]] // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp sgt i64 [[TMP10]], -1 @@ -407,9 +407,9 @@ void test4(struct annotated *p, int index, int fam_idx) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869180, 17179869181) i64 @test4_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sub nsw i64 [[TMP0]], [[TMP1]] // SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i64 [[TMP2]], 2 @@ -422,9 +422,9 @@ void test4(struct annotated *p, int index, int fam_idx) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869180, 17179869181) i64 @test4_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sub nsw i64 [[TMP0]], [[TMP1]] // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i64 [[TMP2]], 2 @@ -523,10 +523,10 @@ size_t test5_bdos(struct anon_struct *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i64, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[DOT_COUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[COUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: // SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] @@ -534,7 +534,7 @@ size_t test5_bdos(struct anon_struct *p) { // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP1]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[DOT_COUNTED_BY_LOAD]], i64 0) +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[COUNTED_BY_LOAD]], i64 0) // SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP2]] to i32 // SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[DOTTR]], 2 // SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] @@ -543,9 +543,9 @@ size_t test5_bdos(struct anon_struct *p) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[DOT_COUNTED_BY_LOAD]], i64 0) +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i64, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[COUNTED_BY_LOAD]], i64 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP0]] to i32 // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[DOTTR]], 2 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 @@ -579,18 +579,18 @@ void test6(struct anon_struct *p, int index) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -3) i64 @test6_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[DOT_COUNTED_BY_LOAD]], i64 0) +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i64, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[COUNTED_BY_LOAD]], i64 0) // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 2 // SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -3) i64 @test6_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[DOT_COUNTED_BY_LOAD]], i64 0) +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i64, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[COUNTED_BY_LOAD]], i64 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 2 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // @@ -684,10 +684,10 @@ size_t test7_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: @@ -696,18 +696,18 @@ size_t test7_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR: cont7: // SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i8 [[DOT_COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: store i8 [[COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[DOT_COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test8( @@ -735,17 +735,17 @@ void test8(struct union_of_fams *p, int index) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 256) i64 @test8_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i64 // SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 256) i64 @test8_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test8_bdos( @@ -838,10 +838,10 @@ size_t test9_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: @@ -850,7 +850,7 @@ size_t test9_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR: cont7: // SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) +// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 // SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] // SANITIZE-WITH-ATTR-NEXT: ret void @@ -858,9 +858,9 @@ size_t test9_bdos(struct union_of_fams *p) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 // NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 @@ -893,18 +893,18 @@ void test10(struct union_of_fams *p, int index) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test10_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64 // SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test10_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] // @@ -1715,10 +1715,10 @@ struct annotated_struct_array { // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA23:![0-9]+]] -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM15:%.*]] = sext i32 [[IDX2]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[IDXPROM15]], [[TMP3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT20:%.*]], label [[HANDLER_OUT_OF_BOUNDS16:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds16: @@ -1727,7 +1727,7 @@ struct annotated_struct_array { // SANITIZE-WITH-ATTR: cont20: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM15]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP5]], 2 // SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret void @@ -1738,9 +1738,9 @@ struct annotated_struct_array { // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX1]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA20:![0-9]+]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP1]], 2 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[IDX2]] to i64 diff --git a/clang/test/CodeGen/mips-vector-return.c b/clang/test/CodeGen/mips-vector-return.c index c2a9bbfe9db02..bd9d9391a5da5 100644 --- a/clang/test/CodeGen/mips-vector-return.c +++ b/clang/test/CodeGen/mips-vector-return.c @@ -8,14 +8,14 @@ typedef float v4sf __attribute__ ((__vector_size__ (16))); typedef double v4df __attribute__ ((__vector_size__ (32))); typedef int v4i32 __attribute__ ((__vector_size__ (16))); -// O32-LABEL: define{{.*}} void @test_v4sf(ptr dead_on_unwind noalias nocapture writable writeonly sret +// O32-LABEL: define{{.*}} void @test_v4sf(ptr {{.*}} sret // N64: define{{.*}} inreg { i64, i64 } @test_v4sf v4sf test_v4sf(float a) { return (v4sf){0.0f, a, 0.0f, 0.0f}; } -// O32-LABEL: define{{.*}} void @test_v4df(ptr dead_on_unwind noalias nocapture writable writeonly sret -// N64-LABEL: define{{.*}} void @test_v4df(ptr dead_on_unwind noalias nocapture writable writeonly sret +// O32-LABEL: define{{.*}} void @test_v4df(ptr {{.*}} sret +// N64-LABEL: define{{.*}} void @test_v4df(ptr {{.*}} sret v4df test_v4df(double a) { return (v4df){0.0, a, 0.0, 0.0}; } diff --git a/clang/test/CodeGen/mips64-nontrivial-return.cpp b/clang/test/CodeGen/mips64-nontrivial-return.cpp index a8fbf4622f803..a038574140bb5 100644 --- a/clang/test/CodeGen/mips64-nontrivial-return.cpp +++ b/clang/test/CodeGen/mips64-nontrivial-return.cpp @@ -10,7 +10,7 @@ class D : public B { extern D gd0; -// CHECK: _Z4foo1v(ptr dead_on_unwind noalias nocapture writable writeonly sret +// CHECK: _Z4foo1v(ptr {{.*}} sret D foo1(void) { return gd0; diff --git a/clang/test/CodeGen/ms-intrinsics-other.c b/clang/test/CodeGen/ms-intrinsics-other.c index fa8422e5bf19f..013277cbf6a2d 100644 --- a/clang/test/CodeGen/ms-intrinsics-other.c +++ b/clang/test/CodeGen/ms-intrinsics-other.c @@ -49,7 +49,7 @@ extern "C" { unsigned char test_BitScanForward(unsigned LONG *Index, unsigned LONG Mask) { return _BitScanForward(Index, Mask); } -// CHECK: define{{.*}}i8 @test_BitScanForward(ptr {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_BitScanForward(ptr {{.*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i32 %Mask, 0 // CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK: [[END_LABEL]]: @@ -63,7 +63,7 @@ unsigned char test_BitScanForward(unsigned LONG *Index, unsigned LONG Mask) { unsigned char test_BitScanReverse(unsigned LONG *Index, unsigned LONG Mask) { return _BitScanReverse(Index, Mask); } -// CHECK: define{{.*}}i8 @test_BitScanReverse(ptr {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_BitScanReverse(ptr {{.*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[0-9]+]] = icmp eq i32 %Mask, 0 // CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK: [[END_LABEL]]: @@ -79,7 +79,7 @@ unsigned char test_BitScanReverse(unsigned LONG *Index, unsigned LONG Mask) { unsigned char test_BitScanForward64(unsigned LONG *Index, unsigned __int64 Mask) { return _BitScanForward64(Index, Mask); } -// CHECK: define{{.*}}i8 @test_BitScanForward64(ptr {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_BitScanForward64(ptr {{.*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i64 %Mask, 0 // CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK: [[END_LABEL]]: @@ -94,7 +94,7 @@ unsigned char test_BitScanForward64(unsigned LONG *Index, unsigned __int64 Mask) unsigned char test_BitScanReverse64(unsigned LONG *Index, unsigned __int64 Mask) { return _BitScanReverse64(Index, Mask); } -// CHECK: define{{.*}}i8 @test_BitScanReverse64(ptr {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_BitScanReverse64(ptr {{.*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[0-9]+]] = icmp eq i64 %Mask, 0 // CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK: [[END_LABEL]]: @@ -111,7 +111,7 @@ unsigned char test_BitScanReverse64(unsigned LONG *Index, unsigned __int64 Mask) LONG test_InterlockedExchange(LONG volatile *value, LONG mask) { return _InterlockedExchange(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedExchange(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedExchange(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -119,7 +119,7 @@ LONG test_InterlockedExchange(LONG volatile *value, LONG mask) { LONG test_InterlockedExchangeAdd(LONG volatile *value, LONG mask) { return _InterlockedExchangeAdd(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedExchangeAdd(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedExchangeAdd(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -127,7 +127,7 @@ LONG test_InterlockedExchangeAdd(LONG volatile *value, LONG mask) { LONG test_InterlockedExchangeSub(LONG volatile *value, LONG mask) { return _InterlockedExchangeSub(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedExchangeSub(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedExchangeSub(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw sub ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -135,7 +135,7 @@ LONG test_InterlockedExchangeSub(LONG volatile *value, LONG mask) { LONG test_InterlockedOr(LONG volatile *value, LONG mask) { return _InterlockedOr(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedOr(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedOr(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -143,7 +143,7 @@ LONG test_InterlockedOr(LONG volatile *value, LONG mask) { LONG test_InterlockedXor(LONG volatile *value, LONG mask) { return _InterlockedXor(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedXor(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedXor(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -151,7 +151,7 @@ LONG test_InterlockedXor(LONG volatile *value, LONG mask) { LONG test_InterlockedAnd(LONG volatile *value, LONG mask) { return _InterlockedAnd(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedAnd(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedAnd(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -168,7 +168,7 @@ LONG test_InterlockedCompareExchange(LONG volatile *Destination, LONG Exchange, LONG test_InterlockedIncrement(LONG volatile *Addend) { return _InterlockedIncrement(Addend); } -// CHECK: define{{.*}}i32 @test_InterlockedIncrement(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedIncrement(ptr{{.*}}%Addend){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i32 1 seq_cst, align 4 // CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 // CHECK: ret i32 [[RESULT]] @@ -177,7 +177,7 @@ LONG test_InterlockedIncrement(LONG volatile *Addend) { LONG test_InterlockedDecrement(LONG volatile *Addend) { return _InterlockedDecrement(Addend); } -// CHECK: define{{.*}}i32 @test_InterlockedDecrement(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedDecrement(ptr{{.*}}%Addend){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i32 1 seq_cst, align 4 // CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 // CHECK: ret i32 [[RESULT]] @@ -236,7 +236,7 @@ LONG test_InterlockedAdd(LONG volatile *Addend, LONG Value) { return _InterlockedAdd(Addend, Value); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAdd(ptr{{[a-z_ ]*}}%Addend, i32 noundef %Value) {{.*}} { +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAdd(ptr{{.*}}%Addend, i32 noundef %Value) {{.*}} { // CHECK-ARM-ARM64: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %Addend, i32 %Value seq_cst, align 4 // CHECK-ARM-ARM64: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %Value // CHECK-ARM-ARM64: ret i32 %[[NEWVAL:[0-9]+]] @@ -245,7 +245,7 @@ __int64 test_InterlockedAdd64(__int64 volatile *Addend, __int64 Value) { return _InterlockedAdd64(Addend, Value); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAdd64(ptr{{[a-z_ ]*}}%Addend, i64 noundef %Value) {{.*}} { +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAdd64(ptr{{.*}}%Addend, i64 noundef %Value) {{.*}} { // CHECK-ARM-ARM64: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %Addend, i64 %Value seq_cst, align 8 // CHECK-ARM-ARM64: %[[NEWVAL:[0-9]+]] = add i64 %[[OLDVAL:[0-9]+]], %Value // CHECK-ARM-ARM64: ret i64 %[[NEWVAL:[0-9]+]] @@ -255,21 +255,21 @@ __int64 test_InterlockedAdd64(__int64 volatile *Addend, __int64 Value) { LONG test_InterlockedExchangeAdd_acq(LONG volatile *value, LONG mask) { return _InterlockedExchangeAdd_acq(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchangeAdd_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchangeAdd_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i32 %mask acquire, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } LONG test_InterlockedExchangeAdd_rel(LONG volatile *value, LONG mask) { return _InterlockedExchangeAdd_rel(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchangeAdd_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchangeAdd_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i32 %mask release, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } LONG test_InterlockedExchangeAdd_nf(LONG volatile *value, LONG mask) { return _InterlockedExchangeAdd_nf(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchangeAdd_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchangeAdd_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -277,21 +277,21 @@ LONG test_InterlockedExchangeAdd_nf(LONG volatile *value, LONG mask) { LONG test_InterlockedExchange_acq(LONG volatile *value, LONG mask) { return _InterlockedExchange_acq(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchange_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchange_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i32 %mask acquire, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } LONG test_InterlockedExchange_rel(LONG volatile *value, LONG mask) { return _InterlockedExchange_rel(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchange_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchange_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i32 %mask release, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } LONG test_InterlockedExchange_nf(LONG volatile *value, LONG mask) { return _InterlockedExchange_nf(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchange_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedExchange_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -299,7 +299,7 @@ LONG test_InterlockedExchange_nf(LONG volatile *value, LONG mask) { LONG test_InterlockedCompareExchange_acq(LONG volatile *Destination, LONG Exchange, LONG Comperand) { return _InterlockedCompareExchange_acq(Destination, Exchange, Comperand); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedCompareExchange_acq(ptr{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedCompareExchange_acq(ptr{{.*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i32 %Comperand, i32 %Exchange acquire acquire, align 4 // CHECK-ARM: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0 // CHECK-ARM: ret i32 [[RESULT]] @@ -308,7 +308,7 @@ LONG test_InterlockedCompareExchange_acq(LONG volatile *Destination, LONG Exchan LONG test_InterlockedCompareExchange_rel(LONG volatile *Destination, LONG Exchange, LONG Comperand) { return _InterlockedCompareExchange_rel(Destination, Exchange, Comperand); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedCompareExchange_rel(ptr{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedCompareExchange_rel(ptr{{.*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i32 %Comperand, i32 %Exchange release monotonic, align 4 // CHECK-ARM: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0 // CHECK-ARM: ret i32 [[RESULT]] @@ -317,7 +317,7 @@ LONG test_InterlockedCompareExchange_rel(LONG volatile *Destination, LONG Exchan LONG test_InterlockedCompareExchange_nf(LONG volatile *Destination, LONG Exchange, LONG Comperand) { return _InterlockedCompareExchange_nf(Destination, Exchange, Comperand); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedCompareExchange_nf(ptr{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedCompareExchange_nf(ptr{{.*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i32 %Comperand, i32 %Exchange monotonic monotonic, align 4 // CHECK-ARM: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0 // CHECK-ARM: ret i32 [[RESULT]] @@ -326,7 +326,7 @@ LONG test_InterlockedCompareExchange_nf(LONG volatile *Destination, LONG Exchang LONG test_InterlockedOr_acq(LONG volatile *value, LONG mask) { return _InterlockedOr_acq(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedOr_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedOr_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i32 %mask acquire, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -334,7 +334,7 @@ LONG test_InterlockedOr_acq(LONG volatile *value, LONG mask) { LONG test_InterlockedOr_rel(LONG volatile *value, LONG mask) { return _InterlockedOr_rel(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedOr_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedOr_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i32 %mask release, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -342,7 +342,7 @@ LONG test_InterlockedOr_rel(LONG volatile *value, LONG mask) { LONG test_InterlockedOr_nf(LONG volatile *value, LONG mask) { return _InterlockedOr_nf(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedOr_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedOr_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -350,7 +350,7 @@ LONG test_InterlockedOr_nf(LONG volatile *value, LONG mask) { LONG test_InterlockedXor_acq(LONG volatile *value, LONG mask) { return _InterlockedXor_acq(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedXor_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedXor_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i32 %mask acquire, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -358,7 +358,7 @@ LONG test_InterlockedXor_acq(LONG volatile *value, LONG mask) { LONG test_InterlockedXor_rel(LONG volatile *value, LONG mask) { return _InterlockedXor_rel(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedXor_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedXor_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i32 %mask release, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -366,7 +366,7 @@ LONG test_InterlockedXor_rel(LONG volatile *value, LONG mask) { LONG test_InterlockedXor_nf(LONG volatile *value, LONG mask) { return _InterlockedXor_nf(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedXor_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedXor_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -374,7 +374,7 @@ LONG test_InterlockedXor_nf(LONG volatile *value, LONG mask) { LONG test_InterlockedAnd_acq(LONG volatile *value, LONG mask) { return _InterlockedAnd_acq(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedAnd_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedAnd_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i32 %mask acquire, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -382,7 +382,7 @@ LONG test_InterlockedAnd_acq(LONG volatile *value, LONG mask) { LONG test_InterlockedAnd_rel(LONG volatile *value, LONG mask) { return _InterlockedAnd_rel(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedAnd_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedAnd_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i32 %mask release, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -390,7 +390,7 @@ LONG test_InterlockedAnd_rel(LONG volatile *value, LONG mask) { LONG test_InterlockedAnd_nf(LONG volatile *value, LONG mask) { return _InterlockedAnd_nf(value, mask); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedAnd_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedAnd_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM: } @@ -399,7 +399,7 @@ LONG test_InterlockedAnd_nf(LONG volatile *value, LONG mask) { LONG test_InterlockedIncrement_acq(LONG volatile *Addend) { return _InterlockedIncrement_acq(Addend); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedIncrement_acq(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedIncrement_acq(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i32 1 acquire, align 4 // CHECK-ARM: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 // CHECK-ARM: ret i32 [[RESULT]] @@ -408,7 +408,7 @@ LONG test_InterlockedIncrement_acq(LONG volatile *Addend) { LONG test_InterlockedIncrement_rel(LONG volatile *Addend) { return _InterlockedIncrement_rel(Addend); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedIncrement_rel(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedIncrement_rel(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i32 1 release, align 4 // CHECK-ARM: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 // CHECK-ARM: ret i32 [[RESULT]] @@ -417,7 +417,7 @@ LONG test_InterlockedIncrement_rel(LONG volatile *Addend) { LONG test_InterlockedIncrement_nf(LONG volatile *Addend) { return _InterlockedIncrement_nf(Addend); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedIncrement_nf(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedIncrement_nf(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i32 1 monotonic, align 4 // CHECK-ARM: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 // CHECK-ARM: ret i32 [[RESULT]] @@ -426,7 +426,7 @@ LONG test_InterlockedIncrement_nf(LONG volatile *Addend) { LONG test_InterlockedDecrement_acq(LONG volatile *Addend) { return _InterlockedDecrement_acq(Addend); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedDecrement_acq(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedDecrement_acq(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i32 1 acquire, align 4 // CHECK-ARM: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 // CHECK-ARM: ret i32 [[RESULT]] @@ -435,7 +435,7 @@ LONG test_InterlockedDecrement_acq(LONG volatile *Addend) { LONG test_InterlockedDecrement_rel(LONG volatile *Addend) { return _InterlockedDecrement_rel(Addend); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedDecrement_rel(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedDecrement_rel(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i32 1 release, align 4 // CHECK-ARM: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 // CHECK-ARM: ret i32 [[RESULT]] @@ -444,7 +444,7 @@ LONG test_InterlockedDecrement_rel(LONG volatile *Addend) { LONG test_InterlockedDecrement_nf(LONG volatile *Addend) { return _InterlockedDecrement_nf(Addend); } -// CHECK-ARM: define{{.*}}i32 @test_InterlockedDecrement_nf(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM: define{{.*}}i32 @test_InterlockedDecrement_nf(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i32 1 monotonic, align 4 // CHECK-ARM: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 // CHECK-ARM: ret i32 [[RESULT]] diff --git a/clang/test/CodeGen/ms-intrinsics.c b/clang/test/CodeGen/ms-intrinsics.c index bb1b95fa7521a..b86662ee6778a 100644 --- a/clang/test/CodeGen/ms-intrinsics.c +++ b/clang/test/CodeGen/ms-intrinsics.c @@ -149,7 +149,7 @@ void *test_AddressOfReturnAddress(void) { unsigned char test_BitScanForward(unsigned long *Index, unsigned long Mask) { return _BitScanForward(++Index, Mask); } -// CHECK: define{{.*}}i8 @test_BitScanForward(ptr {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_BitScanForward(ptr {{.*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i32 %Mask, 0 // CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK: [[END_LABEL]]: @@ -164,7 +164,7 @@ unsigned char test_BitScanForward(unsigned long *Index, unsigned long Mask) { unsigned char test_BitScanReverse(unsigned long *Index, unsigned long Mask) { return _BitScanReverse(++Index, Mask); } -// CHECK: define{{.*}}i8 @test_BitScanReverse(ptr {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_BitScanReverse(ptr {{.*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK: [[ISNOTZERO:%[0-9]+]] = icmp eq i32 %Mask, 0 // CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK: [[END_LABEL]]: @@ -181,7 +181,7 @@ unsigned char test_BitScanReverse(unsigned long *Index, unsigned long Mask) { unsigned char test_BitScanForward64(unsigned long *Index, unsigned __int64 Mask) { return _BitScanForward64(Index, Mask); } -// CHECK-ARM-X64: define{{.*}}i8 @test_BitScanForward64(ptr {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK-ARM-X64: define{{.*}}i8 @test_BitScanForward64(ptr {{.*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK-ARM-X64: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i64 %Mask, 0 // CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK-ARM-X64: [[END_LABEL]]: @@ -196,7 +196,7 @@ unsigned char test_BitScanForward64(unsigned long *Index, unsigned __int64 Mask) unsigned char test_BitScanReverse64(unsigned long *Index, unsigned __int64 Mask) { return _BitScanReverse64(Index, Mask); } -// CHECK-ARM-X64: define{{.*}}i8 @test_BitScanReverse64(ptr {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK-ARM-X64: define{{.*}}i8 @test_BitScanReverse64(ptr {{.*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ // CHECK-ARM-X64: [[ISNOTZERO:%[0-9]+]] = icmp eq i64 %Mask, 0 // CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] // CHECK-ARM-X64: [[END_LABEL]]: @@ -214,7 +214,7 @@ void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) { return _InterlockedExchangePointer(Target, Value); } -// CHECK: define{{.*}}ptr @test_InterlockedExchangePointer(ptr {{[a-z_ ]*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{ +// CHECK: define{{.*}}ptr @test_InterlockedExchangePointer(ptr {{.*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{ // CHECK: %[[VALUE:[0-9]+]] = ptrtoint ptr %Value to [[iPTR:i[0-9]+]] // CHECK: %[[EXCHANGE:[0-9]+]] = atomicrmw xchg ptr %Target, [[iPTR]] %[[VALUE]] seq_cst, align {{4|8}} // CHECK: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXCHANGE]] to ptr @@ -226,7 +226,7 @@ void *test_InterlockedExchangePointer_acq(void * volatile *Target, void *Value) return _InterlockedExchangePointer_acq(Target, Value); } -// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedExchangePointer_acq(ptr {{[a-z_ ]*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedExchangePointer_acq(ptr {{.*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{ // CHECK-ARM-ARM64: %[[VALUE:[0-9]+]] = ptrtoint ptr %Value to [[iPTR:i[0-9]+]] // CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = atomicrmw xchg ptr %Target, [[iPTR]] %[[VALUE]] acquire, align {{4|8}} // CHECK-ARM-ARM64: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXCHANGE]] to ptr @@ -237,7 +237,7 @@ void *test_InterlockedExchangePointer_nf(void * volatile *Target, void *Value) { return _InterlockedExchangePointer_nf(Target, Value); } -// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedExchangePointer_nf(ptr {{[a-z_ ]*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedExchangePointer_nf(ptr {{.*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{ // CHECK-ARM-ARM64: %[[VALUE:[0-9]+]] = ptrtoint ptr %Value to [[iPTR]] // CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = atomicrmw xchg ptr %Target, [[iPTR]] %[[VALUE]] monotonic, align {{4|8}} // CHECK-ARM-ARM64: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXCHANGE]] to ptr @@ -248,7 +248,7 @@ void *test_InterlockedExchangePointer_rel(void * volatile *Target, void *Value) return _InterlockedExchangePointer_rel(Target, Value); } -// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedExchangePointer_rel(ptr {{[a-z_ ]*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedExchangePointer_rel(ptr {{.*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{ // CHECK-ARM-ARM64: %[[VALUE:[0-9]+]] = ptrtoint ptr %Value to [[iPTR]] // CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = atomicrmw xchg ptr %Target, [[iPTR]] %[[VALUE]] release, align {{4|8}} // CHECK-ARM-ARM64: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXCHANGE]] to ptr @@ -261,7 +261,7 @@ void *test_InterlockedCompareExchangePointer(void * volatile *Destination, return _InterlockedCompareExchangePointer(Destination, Exchange, Comparand); } -// CHECK: define{{.*}}ptr @test_InterlockedCompareExchangePointer(ptr {{[a-z_ ]*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{ +// CHECK: define{{.*}}ptr @test_InterlockedCompareExchangePointer(ptr {{.*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{ // CHECK: %[[EXCHANGE:[0-9]+]] = ptrtoint ptr %Exchange to [[iPTR]] // CHECK: %[[COMPARAND:[0-9]+]] = ptrtoint ptr %Comparand to [[iPTR]] // CHECK: %[[XCHG:[0-9]+]] = cmpxchg volatile ptr %[[DEST:.+]], [[iPTR]] %[[COMPARAND:[0-9]+]], [[iPTR]] %[[EXCHANGE:[0-9]+]] seq_cst seq_cst, align {{4|8}} @@ -275,7 +275,7 @@ void *test_InterlockedCompareExchangePointer_nf(void * volatile *Destination, return _InterlockedCompareExchangePointer_nf(Destination, Exchange, Comparand); } -// CHECK: define{{.*}}ptr @test_InterlockedCompareExchangePointer_nf(ptr {{[a-z_ ]*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{ +// CHECK: define{{.*}}ptr @test_InterlockedCompareExchangePointer_nf(ptr {{.*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{ // CHECK: %[[EXCHANGE:[0-9]+]] = ptrtoint ptr %Exchange to [[iPTR]] // CHECK: %[[COMPARAND:[0-9]+]] = ptrtoint ptr %Comparand to [[iPTR]] // CHECK: %[[XCHG:[0-9]+]] = cmpxchg volatile ptr %[[DEST:.+]], [[iPTR]] %[[COMPARAND:[0-9]+]], [[iPTR]] %[[EXCHANGE:[0-9]+]] monotonic monotonic, align {{4|8}} @@ -290,7 +290,7 @@ void *test_InterlockedCompareExchangePointer_acq(void * volatile *Destination, return _InterlockedCompareExchangePointer_acq(Destination, Exchange, Comparand); } -// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedCompareExchangePointer_acq(ptr {{[a-z_ ]*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedCompareExchangePointer_acq(ptr {{.*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{ // CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = ptrtoint ptr %Exchange to [[iPTR]] // CHECK-ARM-ARM64: %[[COMPARAND:[0-9]+]] = ptrtoint ptr %Comparand to [[iPTR]] // CHECK-ARM-ARM64: %[[XCHG:[0-9]+]] = cmpxchg volatile ptr %[[DEST:.+]], [[iPTR]] %[[COMPARAND:[0-9]+]], [[iPTR]] %[[EXCHANGE:[0-9]+]] acquire acquire, align {{4|8}} @@ -305,7 +305,7 @@ void *test_InterlockedCompareExchangePointer_rel(void * volatile *Destination, return _InterlockedCompareExchangePointer_rel(Destination, Exchange, Comparand); } -// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedCompareExchangePointer_rel(ptr {{[a-z_ ]*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedCompareExchangePointer_rel(ptr {{.*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{ // CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = ptrtoint ptr %Exchange to [[iPTR]] // CHECK-ARM-ARM64: %[[COMPARAND:[0-9]+]] = ptrtoint ptr %Comparand to [[iPTR]] // CHECK-ARM-ARM64: %[[XCHG:[0-9]+]] = cmpxchg volatile ptr %[[DEST:.+]], [[iPTR]] %[[COMPARAND:[0-9]+]], [[iPTR]] %[[EXCHANGE:[0-9]+]] release monotonic, align {{4|8}} @@ -318,7 +318,7 @@ void *test_InterlockedCompareExchangePointer_rel(void * volatile *Destination, char test_InterlockedExchange8(char volatile *value, char mask) { return _InterlockedExchange8(value, mask); } -// CHECK: define{{.*}}i8 @test_InterlockedExchange8(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_InterlockedExchange8(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i8 %mask seq_cst, align 1 // CHECK: ret i8 [[RESULT:%[0-9]+]] // CHECK: } @@ -326,7 +326,7 @@ char test_InterlockedExchange8(char volatile *value, char mask) { short test_InterlockedExchange16(short volatile *value, short mask) { return _InterlockedExchange16(value, mask); } -// CHECK: define{{.*}}i16 @test_InterlockedExchange16(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i16 @test_InterlockedExchange16(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i16 %mask seq_cst, align 2 // CHECK: ret i16 [[RESULT:%[0-9]+]] // CHECK: } @@ -334,7 +334,7 @@ short test_InterlockedExchange16(short volatile *value, short mask) { long test_InterlockedExchange(long volatile *value, long mask) { return _InterlockedExchange(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedExchange(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedExchange(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -342,7 +342,7 @@ long test_InterlockedExchange(long volatile *value, long mask) { char test_InterlockedExchangeAdd8(char volatile *value, char mask) { return _InterlockedExchangeAdd8(value, mask); } -// CHECK: define{{.*}}i8 @test_InterlockedExchangeAdd8(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_InterlockedExchangeAdd8(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i8 %mask seq_cst, align 1 // CHECK: ret i8 [[RESULT:%[0-9]+]] // CHECK: } @@ -350,7 +350,7 @@ char test_InterlockedExchangeAdd8(char volatile *value, char mask) { short test_InterlockedExchangeAdd16(short volatile *value, short mask) { return _InterlockedExchangeAdd16(value, mask); } -// CHECK: define{{.*}}i16 @test_InterlockedExchangeAdd16(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i16 @test_InterlockedExchangeAdd16(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i16 %mask seq_cst, align 2 // CHECK: ret i16 [[RESULT:%[0-9]+]] // CHECK: } @@ -358,7 +358,7 @@ short test_InterlockedExchangeAdd16(short volatile *value, short mask) { long test_InterlockedExchangeAdd(long volatile *value, long mask) { return _InterlockedExchangeAdd(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedExchangeAdd(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedExchangeAdd(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -366,7 +366,7 @@ long test_InterlockedExchangeAdd(long volatile *value, long mask) { char test_InterlockedExchangeSub8(char volatile *value, char mask) { return _InterlockedExchangeSub8(value, mask); } -// CHECK: define{{.*}}i8 @test_InterlockedExchangeSub8(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_InterlockedExchangeSub8(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw sub ptr %value, i8 %mask seq_cst, align 1 // CHECK: ret i8 [[RESULT:%[0-9]+]] // CHECK: } @@ -374,7 +374,7 @@ char test_InterlockedExchangeSub8(char volatile *value, char mask) { short test_InterlockedExchangeSub16(short volatile *value, short mask) { return _InterlockedExchangeSub16(value, mask); } -// CHECK: define{{.*}}i16 @test_InterlockedExchangeSub16(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i16 @test_InterlockedExchangeSub16(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw sub ptr %value, i16 %mask seq_cst, align 2 // CHECK: ret i16 [[RESULT:%[0-9]+]] // CHECK: } @@ -382,7 +382,7 @@ short test_InterlockedExchangeSub16(short volatile *value, short mask) { long test_InterlockedExchangeSub(long volatile *value, long mask) { return _InterlockedExchangeSub(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedExchangeSub(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedExchangeSub(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw sub ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -390,7 +390,7 @@ long test_InterlockedExchangeSub(long volatile *value, long mask) { char test_InterlockedOr8(char volatile *value, char mask) { return _InterlockedOr8(value, mask); } -// CHECK: define{{.*}}i8 @test_InterlockedOr8(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_InterlockedOr8(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i8 %mask seq_cst, align 1 // CHECK: ret i8 [[RESULT:%[0-9]+]] // CHECK: } @@ -398,7 +398,7 @@ char test_InterlockedOr8(char volatile *value, char mask) { short test_InterlockedOr16(short volatile *value, short mask) { return _InterlockedOr16(value, mask); } -// CHECK: define{{.*}}i16 @test_InterlockedOr16(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i16 @test_InterlockedOr16(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i16 %mask seq_cst, align 2 // CHECK: ret i16 [[RESULT:%[0-9]+]] // CHECK: } @@ -406,7 +406,7 @@ short test_InterlockedOr16(short volatile *value, short mask) { long test_InterlockedOr(long volatile *value, long mask) { return _InterlockedOr(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedOr(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedOr(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -414,7 +414,7 @@ long test_InterlockedOr(long volatile *value, long mask) { char test_InterlockedXor8(char volatile *value, char mask) { return _InterlockedXor8(value, mask); } -// CHECK: define{{.*}}i8 @test_InterlockedXor8(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_InterlockedXor8(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i8 %mask seq_cst, align 1 // CHECK: ret i8 [[RESULT:%[0-9]+]] // CHECK: } @@ -422,7 +422,7 @@ char test_InterlockedXor8(char volatile *value, char mask) { short test_InterlockedXor16(short volatile *value, short mask) { return _InterlockedXor16(value, mask); } -// CHECK: define{{.*}}i16 @test_InterlockedXor16(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i16 @test_InterlockedXor16(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i16 %mask seq_cst, align 2 // CHECK: ret i16 [[RESULT:%[0-9]+]] // CHECK: } @@ -430,7 +430,7 @@ short test_InterlockedXor16(short volatile *value, short mask) { long test_InterlockedXor(long volatile *value, long mask) { return _InterlockedXor(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedXor(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedXor(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -438,7 +438,7 @@ long test_InterlockedXor(long volatile *value, long mask) { char test_InterlockedAnd8(char volatile *value, char mask) { return _InterlockedAnd8(value, mask); } -// CHECK: define{{.*}}i8 @test_InterlockedAnd8(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i8 @test_InterlockedAnd8(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i8 %mask seq_cst, align 1 // CHECK: ret i8 [[RESULT:%[0-9]+]] // CHECK: } @@ -446,7 +446,7 @@ char test_InterlockedAnd8(char volatile *value, char mask) { short test_InterlockedAnd16(short volatile *value, short mask) { return _InterlockedAnd16(value, mask); } -// CHECK: define{{.*}}i16 @test_InterlockedAnd16(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i16 @test_InterlockedAnd16(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i16 %mask seq_cst, align 2 // CHECK: ret i16 [[RESULT:%[0-9]+]] // CHECK: } @@ -454,7 +454,7 @@ short test_InterlockedAnd16(short volatile *value, short mask) { long test_InterlockedAnd(long volatile *value, long mask) { return _InterlockedAnd(value, mask); } -// CHECK: define{{.*}}i32 @test_InterlockedAnd(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedAnd(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i32 %mask seq_cst, align 4 // CHECK: ret i32 [[RESULT:%[0-9]+]] // CHECK: } @@ -462,7 +462,7 @@ long test_InterlockedAnd(long volatile *value, long mask) { char test_InterlockedCompareExchange8(char volatile *Destination, char Exchange, char Comperand) { return _InterlockedCompareExchange8(Destination, Exchange, Comperand); } -// CHECK: define{{.*}}i8 @test_InterlockedCompareExchange8(ptr{{[a-z_ ]*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK: define{{.*}}i8 @test_InterlockedCompareExchange8(ptr{{.*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i8 %Comperand, i8 %Exchange seq_cst seq_cst, align 1 // CHECK: [[RESULT:%[0-9]+]] = extractvalue { i8, i1 } [[TMP]], 0 // CHECK: ret i8 [[RESULT]] @@ -471,7 +471,7 @@ char test_InterlockedCompareExchange8(char volatile *Destination, char Exchange, short test_InterlockedCompareExchange16(short volatile *Destination, short Exchange, short Comperand) { return _InterlockedCompareExchange16(Destination, Exchange, Comperand); } -// CHECK: define{{.*}}i16 @test_InterlockedCompareExchange16(ptr{{[a-z_ ]*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK: define{{.*}}i16 @test_InterlockedCompareExchange16(ptr{{.*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i16 %Comperand, i16 %Exchange seq_cst seq_cst, align 2 // CHECK: [[RESULT:%[0-9]+]] = extractvalue { i16, i1 } [[TMP]], 0 // CHECK: ret i16 [[RESULT]] @@ -480,7 +480,7 @@ short test_InterlockedCompareExchange16(short volatile *Destination, short Excha long test_InterlockedCompareExchange(long volatile *Destination, long Exchange, long Comperand) { return _InterlockedCompareExchange(Destination, Exchange, Comperand); } -// CHECK: define{{.*}}i32 @test_InterlockedCompareExchange(ptr{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedCompareExchange(ptr{{.*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i32 %Comperand, i32 %Exchange seq_cst seq_cst, align 4 // CHECK: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0 // CHECK: ret i32 [[RESULT]] @@ -489,7 +489,7 @@ long test_InterlockedCompareExchange(long volatile *Destination, long Exchange, __int64 test_InterlockedCompareExchange64(__int64 volatile *Destination, __int64 Exchange, __int64 Comperand) { return _InterlockedCompareExchange64(Destination, Exchange, Comperand); } -// CHECK: define{{.*}}i64 @test_InterlockedCompareExchange64(ptr{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK: define{{.*}}i64 @test_InterlockedCompareExchange64(ptr{{.*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i64 %Comperand, i64 %Exchange seq_cst seq_cst, align 8 // CHECK: [[RESULT:%[0-9]+]] = extractvalue { i64, i1 } [[TMP]], 0 // CHECK: ret i64 [[RESULT]] @@ -502,7 +502,7 @@ unsigned char test_InterlockedCompareExchange128( return _InterlockedCompareExchange128(++Destination, ++ExchangeHigh, ++ExchangeLow, ++ComparandResult); } -// CHECK-64: define{{.*}}i8 @test_InterlockedCompareExchange128(ptr{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%ExchangeHigh, i64{{[a-z_ ]*}}%ExchangeLow, ptr{{[a-z_ ]*}}%ComparandResult){{.*}}{ +// CHECK-64: define{{.*}}i8 @test_InterlockedCompareExchange128(ptr{{.*}}%Destination, i64{{[a-z_ ]*}}%ExchangeHigh, i64{{[a-z_ ]*}}%ExchangeLow, ptr{{.*}}%ComparandResult){{.*}}{ // CHECK-64: %incdec.ptr = getelementptr inbounds nuw i8, ptr %Destination, i64 8 // CHECK-64: %inc = add nsw i64 %ExchangeHigh, 1 // CHECK-64: %inc1 = add nsw i64 %ExchangeLow, 1 @@ -551,7 +551,7 @@ unsigned char test_InterlockedCompareExchange128_rel( short test_InterlockedIncrement16(short volatile *Addend) { return _InterlockedIncrement16(++Addend); } -// CHECK: define{{.*}}i16 @test_InterlockedIncrement16(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: define{{.*}}i16 @test_InterlockedIncrement16(ptr{{.*}}%Addend){{.*}}{ // CHECK: %incdec.ptr = getelementptr inbounds nuw i8, ptr %Addend, {{i64|i32}} 2 // CHECK: [[TMP:%[0-9]+]] = atomicrmw add ptr %incdec.ptr, i16 1 seq_cst, align 2 // CHECK: [[RESULT:%[0-9]+]] = add i16 [[TMP]], 1 @@ -561,7 +561,7 @@ short test_InterlockedIncrement16(short volatile *Addend) { long test_InterlockedIncrement(long volatile *Addend) { return _InterlockedIncrement(++Addend); } -// CHECK: define{{.*}}i32 @test_InterlockedIncrement(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedIncrement(ptr{{.*}}%Addend){{.*}}{ // CHECK: %incdec.ptr = getelementptr inbounds nuw i8, ptr %Addend, {{i64|i32}} 4 // CHECK: [[TMP:%[0-9]+]] = atomicrmw add ptr %incdec.ptr, i32 1 seq_cst, align 4 // CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 @@ -571,7 +571,7 @@ long test_InterlockedIncrement(long volatile *Addend) { short test_InterlockedDecrement16(short volatile *Addend) { return _InterlockedDecrement16(Addend); } -// CHECK: define{{.*}}i16 @test_InterlockedDecrement16(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: define{{.*}}i16 @test_InterlockedDecrement16(ptr{{.*}}%Addend){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i16 1 seq_cst, align 2 // CHECK: [[RESULT:%[0-9]+]] = add i16 [[TMP]], -1 // CHECK: ret i16 [[RESULT]] @@ -580,7 +580,7 @@ short test_InterlockedDecrement16(short volatile *Addend) { long test_InterlockedDecrement(long volatile *Addend) { return _InterlockedDecrement(Addend); } -// CHECK: define{{.*}}i32 @test_InterlockedDecrement(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: define{{.*}}i32 @test_InterlockedDecrement(ptr{{.*}}%Addend){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i32 1 seq_cst, align 4 // CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 // CHECK: ret i32 [[RESULT]] @@ -591,13 +591,13 @@ short test_iso_volatile_load16(short volatile *p) { return __iso_volatile_load16 int test_iso_volatile_load32(int volatile *p) { return __iso_volatile_load32(p); } __int64 test_iso_volatile_load64(__int64 volatile *p) { return __iso_volatile_load64(p); } -// CHECK: define{{.*}}i8 @test_iso_volatile_load8(ptr{{[a-z_ ]*}}%p) +// CHECK: define{{.*}}i8 @test_iso_volatile_load8(ptr{{.*}}%p) // CHECK: = load volatile i8, ptr %p -// CHECK: define{{.*}}i16 @test_iso_volatile_load16(ptr{{[a-z_ ]*}}%p) +// CHECK: define{{.*}}i16 @test_iso_volatile_load16(ptr{{.*}}%p) // CHECK: = load volatile i16, ptr %p -// CHECK: define{{.*}}i32 @test_iso_volatile_load32(ptr{{[a-z_ ]*}}%p) +// CHECK: define{{.*}}i32 @test_iso_volatile_load32(ptr{{.*}}%p) // CHECK: = load volatile i32, ptr %p -// CHECK: define{{.*}}i64 @test_iso_volatile_load64(ptr{{[a-z_ ]*}}%p) +// CHECK: define{{.*}}i64 @test_iso_volatile_load64(ptr{{.*}}%p) // CHECK: = load volatile i64, ptr %p void test_iso_volatile_store8(char volatile *p, char v) { __iso_volatile_store8(p, v); } @@ -605,13 +605,13 @@ void test_iso_volatile_store16(short volatile *p, short v) { __iso_volatile_stor void test_iso_volatile_store32(int volatile *p, int v) { __iso_volatile_store32(p, v); } void test_iso_volatile_store64(__int64 volatile *p, __int64 v) { __iso_volatile_store64(p, v); } -// CHECK: define{{.*}}void @test_iso_volatile_store8(ptr{{[a-z_ ]*}}%p, i8 {{[a-z_ ]*}}%v) +// CHECK: define{{.*}}void @test_iso_volatile_store8(ptr{{.*}}%p, i8 {{[a-z_ ]*}}%v) // CHECK: store volatile i8 %v, ptr %p -// CHECK: define{{.*}}void @test_iso_volatile_store16(ptr{{[a-z_ ]*}}%p, i16 {{[a-z_ ]*}}%v) +// CHECK: define{{.*}}void @test_iso_volatile_store16(ptr{{.*}}%p, i16 {{[a-z_ ]*}}%v) // CHECK: store volatile i16 %v, ptr %p -// CHECK: define{{.*}}void @test_iso_volatile_store32(ptr{{[a-z_ ]*}}%p, i32 {{[a-z_ ]*}}%v) +// CHECK: define{{.*}}void @test_iso_volatile_store32(ptr{{.*}}%p, i32 {{[a-z_ ]*}}%v) // CHECK: store volatile i32 %v, ptr %p -// CHECK: define{{.*}}void @test_iso_volatile_store64(ptr{{[a-z_ ]*}}%p, i64 {{[a-z_ ]*}}%v) +// CHECK: define{{.*}}void @test_iso_volatile_store64(ptr{{.*}}%p, i64 {{[a-z_ ]*}}%v) // CHECK: store volatile i64 %v, ptr %p @@ -619,7 +619,7 @@ void test_iso_volatile_store64(__int64 volatile *p, __int64 v) { __iso_volatile_ __int64 test_InterlockedExchange64(__int64 volatile *value, __int64 mask) { return _InterlockedExchange64(value, mask); } -// CHECK: define{{.*}}i64 @test_InterlockedExchange64(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i64 @test_InterlockedExchange64(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i64 %mask seq_cst, align 8 // CHECK: ret i64 [[RESULT:%[0-9]+]] // CHECK: } @@ -627,7 +627,7 @@ __int64 test_InterlockedExchange64(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedExchangeAdd64(__int64 volatile *value, __int64 mask) { return _InterlockedExchangeAdd64(value, mask); } -// CHECK: define{{.*}}i64 @test_InterlockedExchangeAdd64(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i64 @test_InterlockedExchangeAdd64(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i64 %mask seq_cst, align 8 // CHECK: ret i64 [[RESULT:%[0-9]+]] // CHECK: } @@ -635,7 +635,7 @@ __int64 test_InterlockedExchangeAdd64(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedExchangeSub64(__int64 volatile *value, __int64 mask) { return _InterlockedExchangeSub64(value, mask); } -// CHECK: define{{.*}}i64 @test_InterlockedExchangeSub64(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i64 @test_InterlockedExchangeSub64(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw sub ptr %value, i64 %mask seq_cst, align 8 // CHECK: ret i64 [[RESULT:%[0-9]+]] // CHECK: } @@ -643,7 +643,7 @@ __int64 test_InterlockedExchangeSub64(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedOr64(__int64 volatile *value, __int64 mask) { return _InterlockedOr64(value, mask); } -// CHECK: define{{.*}}i64 @test_InterlockedOr64(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i64 @test_InterlockedOr64(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i64 %mask seq_cst, align 8 // CHECK: ret i64 [[RESULT:%[0-9]+]] // CHECK: } @@ -651,7 +651,7 @@ __int64 test_InterlockedOr64(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedXor64(__int64 volatile *value, __int64 mask) { return _InterlockedXor64(value, mask); } -// CHECK: define{{.*}}i64 @test_InterlockedXor64(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i64 @test_InterlockedXor64(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i64 %mask seq_cst, align 8 // CHECK: ret i64 [[RESULT:%[0-9]+]] // CHECK: } @@ -659,7 +659,7 @@ __int64 test_InterlockedXor64(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedAnd64(__int64 volatile *value, __int64 mask) { return _InterlockedAnd64(value, mask); } -// CHECK: define{{.*}}i64 @test_InterlockedAnd64(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: define{{.*}}i64 @test_InterlockedAnd64(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i64 %mask seq_cst, align 8 // CHECK: ret i64 [[RESULT:%[0-9]+]] // CHECK: } @@ -667,7 +667,7 @@ __int64 test_InterlockedAnd64(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedIncrement64(__int64 volatile *Addend) { return _InterlockedIncrement64(Addend); } -// CHECK: define{{.*}}i64 @test_InterlockedIncrement64(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: define{{.*}}i64 @test_InterlockedIncrement64(ptr{{.*}}%Addend){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i64 1 seq_cst, align 8 // CHECK: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1 // CHECK: ret i64 [[RESULT]] @@ -676,7 +676,7 @@ __int64 test_InterlockedIncrement64(__int64 volatile *Addend) { __int64 test_InterlockedDecrement64(__int64 volatile *Addend) { return _InterlockedDecrement64(Addend); } -// CHECK: define{{.*}}i64 @test_InterlockedDecrement64(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: define{{.*}}i64 @test_InterlockedDecrement64(ptr{{.*}}%Addend){{.*}}{ // CHECK: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i64 1 seq_cst, align 8 // CHECK: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1 // CHECK: ret i64 [[RESULT]] @@ -686,48 +686,48 @@ __int64 test_InterlockedDecrement64(__int64 volatile *Addend) { #if defined(__i386__) || defined(__x86_64__) long test_InterlockedExchange_HLEAcquire(long volatile *Target, long Value) { -// CHECK-INTEL: define{{.*}} i32 @test_InterlockedExchange_HLEAcquire(ptr{{[a-z_ ]*}}%Target, i32{{[a-z_ ]*}}%Value) +// CHECK-INTEL: define{{.*}} i32 @test_InterlockedExchange_HLEAcquire(ptr{{.*}}%Target, i32{{[a-z_ ]*}}%Value) // CHECK-INTEL: call i32 asm sideeffect ".byte 0xf2 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) %Target, i32 %Value, ptr elementtype(i32) %Target) return _InterlockedExchange_HLEAcquire(Target, Value); } long test_InterlockedExchange_HLERelease(long volatile *Target, long Value) { -// CHECK-INTEL: define{{.*}} i32 @test_InterlockedExchange_HLERelease(ptr{{[a-z_ ]*}}%Target, i32{{[a-z_ ]*}}%Value) +// CHECK-INTEL: define{{.*}} i32 @test_InterlockedExchange_HLERelease(ptr{{.*}}%Target, i32{{[a-z_ ]*}}%Value) // CHECK-INTEL: call i32 asm sideeffect ".byte 0xf3 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) %Target, i32 %Value, ptr elementtype(i32) %Target) return _InterlockedExchange_HLERelease(Target, Value); } long test_InterlockedCompareExchange_HLEAcquire(long volatile *Destination, long Exchange, long Comparand) { -// CHECK-INTEL: define{{.*}} i32 @test_InterlockedCompareExchange_HLEAcquire(ptr{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comparand) +// CHECK-INTEL: define{{.*}} i32 @test_InterlockedCompareExchange_HLEAcquire(ptr{{.*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comparand) // CHECK-INTEL: call i32 asm sideeffect ".byte 0xf2 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) %Destination, i32 %Exchange, i32 %Comparand, ptr elementtype(i32) %Destination) return _InterlockedCompareExchange_HLEAcquire(Destination, Exchange, Comparand); } long test_InterlockedCompareExchange_HLERelease(long volatile *Destination, long Exchange, long Comparand) { -// CHECK-INTEL: define{{.*}} i32 @test_InterlockedCompareExchange_HLERelease(ptr{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comparand) +// CHECK-INTEL: define{{.*}} i32 @test_InterlockedCompareExchange_HLERelease(ptr{{.*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comparand) // CHECK-INTEL: call i32 asm sideeffect ".byte 0xf3 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i32) %Destination, i32 %Exchange, i32 %Comparand, ptr elementtype(i32) %Destination) return _InterlockedCompareExchange_HLERelease(Destination, Exchange, Comparand); } #endif #if defined(__x86_64__) __int64 test_InterlockedExchange64_HLEAcquire(__int64 volatile *Target, __int64 Value) { -// CHECK-X64: define{{.*}} i64 @test_InterlockedExchange64_HLEAcquire(ptr{{[a-z_ ]*}}%Target, i64{{[a-z_ ]*}}%Value) +// CHECK-X64: define{{.*}} i64 @test_InterlockedExchange64_HLEAcquire(ptr{{.*}}%Target, i64{{[a-z_ ]*}}%Value) // CHECK-X64: call i64 asm sideeffect ".byte 0xf2 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i64) %Target, i64 %Value, ptr elementtype(i64) %Target) return _InterlockedExchange64_HLEAcquire(Target, Value); } __int64 test_InterlockedExchange64_HLERelease(__int64 volatile *Target, __int64 Value) { -// CHECK-X64: define{{.*}} i64 @test_InterlockedExchange64_HLERelease(ptr{{[a-z_ ]*}}%Target, i64{{[a-z_ ]*}}%Value) +// CHECK-X64: define{{.*}} i64 @test_InterlockedExchange64_HLERelease(ptr{{.*}}%Target, i64{{[a-z_ ]*}}%Value) // CHECK-X64: call i64 asm sideeffect ".byte 0xf3 ; lock ; xchg $($0, $1$|$1, $0$)", "=r,=*m,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i64) %Target, i64 %Value, ptr elementtype(i64) %Target) return _InterlockedExchange64_HLERelease(Target, Value); } __int64 test_InterlockedCompareExchange64_HLEAcquire(__int64 volatile *Destination, __int64 Exchange, __int64 Comparand) { -// CHECK-X64: define{{.*}} i64 @test_InterlockedCompareExchange64_HLEAcquire(ptr{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comparand) +// CHECK-X64: define{{.*}} i64 @test_InterlockedCompareExchange64_HLEAcquire(ptr{{.*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comparand) // CHECK-X64: call i64 asm sideeffect ".byte 0xf2 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i64) %Destination, i64 %Exchange, i64 %Comparand, ptr elementtype(i64) %Destination) return _InterlockedCompareExchange64_HLEAcquire(Destination, Exchange, Comparand); } __int64 test_InterlockedCompareExchange64_HLERelease(__int64 volatile *Destination, __int64 Exchange, __int64 Comparand) { -// CHECK-X64: define{{.*}} i64 @test_InterlockedCompareExchange64_HLERelease(ptr{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comparand) +// CHECK-X64: define{{.*}} i64 @test_InterlockedCompareExchange64_HLERelease(ptr{{.*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comparand) // CHECK-X64: call i64 asm sideeffect ".byte 0xf3 ; lock ; cmpxchg $($2, $1$|$1, $2$)", "={ax},=*m,r,0,*m,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(i64) %Destination, i64 %Exchange, i64 %Comparand, ptr elementtype(i64) %Destination) return _InterlockedCompareExchange64_HLERelease(Destination, Exchange, Comparand); } @@ -737,84 +737,84 @@ __int64 test_InterlockedCompareExchange64_HLERelease(__int64 volatile *Destinati char test_InterlockedExchangeAdd8_acq(char volatile *value, char mask) { return _InterlockedExchangeAdd8_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_acq(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_acq(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i8 %mask acquire, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } char test_InterlockedExchangeAdd8_rel(char volatile *value, char mask) { return _InterlockedExchangeAdd8_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_rel(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_rel(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i8 %mask release, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } char test_InterlockedExchangeAdd8_nf(char volatile *value, char mask) { return _InterlockedExchangeAdd8_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_nf(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_nf(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i8 %mask monotonic, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } short test_InterlockedExchangeAdd16_acq(short volatile *value, short mask) { return _InterlockedExchangeAdd16_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_acq(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_acq(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i16 %mask acquire, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } short test_InterlockedExchangeAdd16_rel(short volatile *value, short mask) { return _InterlockedExchangeAdd16_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_rel(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_rel(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i16 %mask release, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } short test_InterlockedExchangeAdd16_nf(short volatile *value, short mask) { return _InterlockedExchangeAdd16_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_nf(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_nf(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i16 %mask monotonic, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } long test_InterlockedExchangeAdd_acq(long volatile *value, long mask) { return _InterlockedExchangeAdd_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i32 %mask acquire, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } long test_InterlockedExchangeAdd_rel(long volatile *value, long mask) { return _InterlockedExchangeAdd_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i32 %mask release, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } long test_InterlockedExchangeAdd_nf(long volatile *value, long mask) { return _InterlockedExchangeAdd_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } __int64 test_InterlockedExchangeAdd64_acq(__int64 volatile *value, __int64 mask) { return _InterlockedExchangeAdd64_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_acq(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_acq(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i64 %mask acquire, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } __int64 test_InterlockedExchangeAdd64_rel(__int64 volatile *value, __int64 mask) { return _InterlockedExchangeAdd64_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_rel(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_rel(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i64 %mask release, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } __int64 test_InterlockedExchangeAdd64_nf(__int64 volatile *value, __int64 mask) { return _InterlockedExchangeAdd64_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_nf(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_nf(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add ptr %value, i64 %mask monotonic, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -822,84 +822,84 @@ __int64 test_InterlockedExchangeAdd64_nf(__int64 volatile *value, __int64 mask) char test_InterlockedExchange8_acq(char volatile *value, char mask) { return _InterlockedExchange8_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchange8_acq(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchange8_acq(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i8 %mask acquire, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } char test_InterlockedExchange8_rel(char volatile *value, char mask) { return _InterlockedExchange8_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchange8_rel(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchange8_rel(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i8 %mask release, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } char test_InterlockedExchange8_nf(char volatile *value, char mask) { return _InterlockedExchange8_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchange8_nf(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchange8_nf(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i8 %mask monotonic, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } short test_InterlockedExchange16_acq(short volatile *value, short mask) { return _InterlockedExchange16_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchange16_acq(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchange16_acq(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i16 %mask acquire, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } short test_InterlockedExchange16_rel(short volatile *value, short mask) { return _InterlockedExchange16_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchange16_rel(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchange16_rel(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i16 %mask release, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } short test_InterlockedExchange16_nf(short volatile *value, short mask) { return _InterlockedExchange16_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchange16_nf(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchange16_nf(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i16 %mask monotonic, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } long test_InterlockedExchange_acq(long volatile *value, long mask) { return _InterlockedExchange_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchange_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchange_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i32 %mask acquire, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } long test_InterlockedExchange_rel(long volatile *value, long mask) { return _InterlockedExchange_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchange_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchange_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i32 %mask release, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } long test_InterlockedExchange_nf(long volatile *value, long mask) { return _InterlockedExchange_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchange_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchange_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } __int64 test_InterlockedExchange64_acq(__int64 volatile *value, __int64 mask) { return _InterlockedExchange64_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchange64_acq(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchange64_acq(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i64 %mask acquire, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } __int64 test_InterlockedExchange64_rel(__int64 volatile *value, __int64 mask) { return _InterlockedExchange64_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchange64_rel(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchange64_rel(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i64 %mask release, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } __int64 test_InterlockedExchange64_nf(__int64 volatile *value, __int64 mask) { return _InterlockedExchange64_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchange64_nf(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchange64_nf(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xchg ptr %value, i64 %mask monotonic, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -907,7 +907,7 @@ __int64 test_InterlockedExchange64_nf(__int64 volatile *value, __int64 mask) { char test_InterlockedCompareExchange8_acq(char volatile *Destination, char Exchange, char Comperand) { return _InterlockedCompareExchange8_acq(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedCompareExchange8_acq(ptr{{[a-z_ ]*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedCompareExchange8_acq(ptr{{.*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i8 %Comperand, i8 %Exchange acquire acquire, align 1 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i8, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i8 [[RESULT]] @@ -916,7 +916,7 @@ char test_InterlockedCompareExchange8_acq(char volatile *Destination, char Excha char test_InterlockedCompareExchange8_rel(char volatile *Destination, char Exchange, char Comperand) { return _InterlockedCompareExchange8_rel(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedCompareExchange8_rel(ptr{{[a-z_ ]*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedCompareExchange8_rel(ptr{{.*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i8 %Comperand, i8 %Exchange release monotonic, align 1 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i8, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i8 [[RESULT]] @@ -925,7 +925,7 @@ char test_InterlockedCompareExchange8_rel(char volatile *Destination, char Excha char test_InterlockedCompareExchange8_nf(char volatile *Destination, char Exchange, char Comperand) { return _InterlockedCompareExchange8_nf(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedCompareExchange8_nf(ptr{{[a-z_ ]*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedCompareExchange8_nf(ptr{{.*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i8 %Comperand, i8 %Exchange monotonic monotonic, align 1 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i8, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i8 [[RESULT]] @@ -934,7 +934,7 @@ char test_InterlockedCompareExchange8_nf(char volatile *Destination, char Exchan short test_InterlockedCompareExchange16_acq(short volatile *Destination, short Exchange, short Comperand) { return _InterlockedCompareExchange16_acq(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedCompareExchange16_acq(ptr{{[a-z_ ]*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedCompareExchange16_acq(ptr{{.*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i16 %Comperand, i16 %Exchange acquire acquire, align 2 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i16, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i16 [[RESULT]] @@ -943,7 +943,7 @@ short test_InterlockedCompareExchange16_acq(short volatile *Destination, short E short test_InterlockedCompareExchange16_rel(short volatile *Destination, short Exchange, short Comperand) { return _InterlockedCompareExchange16_rel(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedCompareExchange16_rel(ptr{{[a-z_ ]*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedCompareExchange16_rel(ptr{{.*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i16 %Comperand, i16 %Exchange release monotonic, align 2 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i16, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i16 [[RESULT]] @@ -952,7 +952,7 @@ short test_InterlockedCompareExchange16_rel(short volatile *Destination, short E short test_InterlockedCompareExchange16_nf(short volatile *Destination, short Exchange, short Comperand) { return _InterlockedCompareExchange16_nf(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedCompareExchange16_nf(ptr{{[a-z_ ]*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedCompareExchange16_nf(ptr{{.*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i16 %Comperand, i16 %Exchange monotonic monotonic, align 2 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i16, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i16 [[RESULT]] @@ -961,7 +961,7 @@ short test_InterlockedCompareExchange16_nf(short volatile *Destination, short Ex long test_InterlockedCompareExchange_acq(long volatile *Destination, long Exchange, long Comperand) { return _InterlockedCompareExchange_acq(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedCompareExchange_acq(ptr{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedCompareExchange_acq(ptr{{.*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i32 %Comperand, i32 %Exchange acquire acquire, align 4 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i32 [[RESULT]] @@ -970,7 +970,7 @@ long test_InterlockedCompareExchange_acq(long volatile *Destination, long Exchan long test_InterlockedCompareExchange_rel(long volatile *Destination, long Exchange, long Comperand) { return _InterlockedCompareExchange_rel(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedCompareExchange_rel(ptr{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedCompareExchange_rel(ptr{{.*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i32 %Comperand, i32 %Exchange release monotonic, align 4 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i32 [[RESULT]] @@ -979,7 +979,7 @@ long test_InterlockedCompareExchange_rel(long volatile *Destination, long Exchan long test_InterlockedCompareExchange_nf(long volatile *Destination, long Exchange, long Comperand) { return _InterlockedCompareExchange_nf(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedCompareExchange_nf(ptr{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedCompareExchange_nf(ptr{{.*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i32 %Comperand, i32 %Exchange monotonic monotonic, align 4 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i32 [[RESULT]] @@ -988,7 +988,7 @@ long test_InterlockedCompareExchange_nf(long volatile *Destination, long Exchang __int64 test_InterlockedCompareExchange64_acq(__int64 volatile *Destination, __int64 Exchange, __int64 Comperand) { return _InterlockedCompareExchange64_acq(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedCompareExchange64_acq(ptr{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedCompareExchange64_acq(ptr{{.*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i64 %Comperand, i64 %Exchange acquire acquire, align 8 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i64, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i64 [[RESULT]] @@ -997,7 +997,7 @@ __int64 test_InterlockedCompareExchange64_acq(__int64 volatile *Destination, __i __int64 test_InterlockedCompareExchange64_rel(__int64 volatile *Destination, __int64 Exchange, __int64 Comperand) { return _InterlockedCompareExchange64_rel(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedCompareExchange64_rel(ptr{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedCompareExchange64_rel(ptr{{.*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i64 %Comperand, i64 %Exchange release monotonic, align 8 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i64, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i64 [[RESULT]] @@ -1006,7 +1006,7 @@ __int64 test_InterlockedCompareExchange64_rel(__int64 volatile *Destination, __i __int64 test_InterlockedCompareExchange64_nf(__int64 volatile *Destination, __int64 Exchange, __int64 Comperand) { return _InterlockedCompareExchange64_nf(Destination, Exchange, Comperand); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedCompareExchange64_nf(ptr{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedCompareExchange64_nf(ptr{{.*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = cmpxchg volatile ptr %Destination, i64 %Comperand, i64 %Exchange monotonic monotonic, align 8 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = extractvalue { i64, i1 } [[TMP]], 0 // CHECK-ARM-ARM64: ret i64 [[RESULT]] @@ -1015,7 +1015,7 @@ __int64 test_InterlockedCompareExchange64_nf(__int64 volatile *Destination, __in char test_InterlockedOr8_acq(char volatile *value, char mask) { return _InterlockedOr8_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedOr8_acq(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedOr8_acq(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i8 %mask acquire, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1023,7 +1023,7 @@ char test_InterlockedOr8_acq(char volatile *value, char mask) { char test_InterlockedOr8_rel(char volatile *value, char mask) { return _InterlockedOr8_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedOr8_rel(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedOr8_rel(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i8 %mask release, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1031,7 +1031,7 @@ char test_InterlockedOr8_rel(char volatile *value, char mask) { char test_InterlockedOr8_nf(char volatile *value, char mask) { return _InterlockedOr8_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedOr8_nf(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedOr8_nf(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i8 %mask monotonic, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1039,7 +1039,7 @@ char test_InterlockedOr8_nf(char volatile *value, char mask) { short test_InterlockedOr16_acq(short volatile *value, short mask) { return _InterlockedOr16_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedOr16_acq(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedOr16_acq(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i16 %mask acquire, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1047,7 +1047,7 @@ short test_InterlockedOr16_acq(short volatile *value, short mask) { short test_InterlockedOr16_rel(short volatile *value, short mask) { return _InterlockedOr16_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedOr16_rel(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedOr16_rel(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i16 %mask release, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1055,7 +1055,7 @@ short test_InterlockedOr16_rel(short volatile *value, short mask) { short test_InterlockedOr16_nf(short volatile *value, short mask) { return _InterlockedOr16_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedOr16_nf(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedOr16_nf(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i16 %mask monotonic, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1063,7 +1063,7 @@ short test_InterlockedOr16_nf(short volatile *value, short mask) { long test_InterlockedOr_acq(long volatile *value, long mask) { return _InterlockedOr_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedOr_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedOr_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i32 %mask acquire, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1071,7 +1071,7 @@ long test_InterlockedOr_acq(long volatile *value, long mask) { long test_InterlockedOr_rel(long volatile *value, long mask) { return _InterlockedOr_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedOr_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedOr_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i32 %mask release, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1079,7 +1079,7 @@ long test_InterlockedOr_rel(long volatile *value, long mask) { long test_InterlockedOr_nf(long volatile *value, long mask) { return _InterlockedOr_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedOr_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedOr_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1087,7 +1087,7 @@ long test_InterlockedOr_nf(long volatile *value, long mask) { __int64 test_InterlockedOr64_acq(__int64 volatile *value, __int64 mask) { return _InterlockedOr64_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedOr64_acq(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedOr64_acq(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i64 %mask acquire, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1095,7 +1095,7 @@ __int64 test_InterlockedOr64_acq(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedOr64_rel(__int64 volatile *value, __int64 mask) { return _InterlockedOr64_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedOr64_rel(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedOr64_rel(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i64 %mask release, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1103,7 +1103,7 @@ __int64 test_InterlockedOr64_rel(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedOr64_nf(__int64 volatile *value, __int64 mask) { return _InterlockedOr64_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedOr64_nf(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedOr64_nf(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw or ptr %value, i64 %mask monotonic, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1111,7 +1111,7 @@ __int64 test_InterlockedOr64_nf(__int64 volatile *value, __int64 mask) { char test_InterlockedXor8_acq(char volatile *value, char mask) { return _InterlockedXor8_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedXor8_acq(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedXor8_acq(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i8 %mask acquire, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1119,7 +1119,7 @@ char test_InterlockedXor8_acq(char volatile *value, char mask) { char test_InterlockedXor8_rel(char volatile *value, char mask) { return _InterlockedXor8_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedXor8_rel(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedXor8_rel(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i8 %mask release, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1127,7 +1127,7 @@ char test_InterlockedXor8_rel(char volatile *value, char mask) { char test_InterlockedXor8_nf(char volatile *value, char mask) { return _InterlockedXor8_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedXor8_nf(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedXor8_nf(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i8 %mask monotonic, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1135,7 +1135,7 @@ char test_InterlockedXor8_nf(char volatile *value, char mask) { short test_InterlockedXor16_acq(short volatile *value, short mask) { return _InterlockedXor16_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedXor16_acq(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedXor16_acq(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i16 %mask acquire, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1143,7 +1143,7 @@ short test_InterlockedXor16_acq(short volatile *value, short mask) { short test_InterlockedXor16_rel(short volatile *value, short mask) { return _InterlockedXor16_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedXor16_rel(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedXor16_rel(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i16 %mask release, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1151,7 +1151,7 @@ short test_InterlockedXor16_rel(short volatile *value, short mask) { short test_InterlockedXor16_nf(short volatile *value, short mask) { return _InterlockedXor16_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedXor16_nf(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedXor16_nf(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i16 %mask monotonic, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1159,7 +1159,7 @@ short test_InterlockedXor16_nf(short volatile *value, short mask) { long test_InterlockedXor_acq(long volatile *value, long mask) { return _InterlockedXor_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedXor_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedXor_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i32 %mask acquire, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1167,7 +1167,7 @@ long test_InterlockedXor_acq(long volatile *value, long mask) { long test_InterlockedXor_rel(long volatile *value, long mask) { return _InterlockedXor_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedXor_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedXor_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i32 %mask release, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1175,7 +1175,7 @@ long test_InterlockedXor_rel(long volatile *value, long mask) { long test_InterlockedXor_nf(long volatile *value, long mask) { return _InterlockedXor_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedXor_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedXor_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1183,7 +1183,7 @@ long test_InterlockedXor_nf(long volatile *value, long mask) { __int64 test_InterlockedXor64_acq(__int64 volatile *value, __int64 mask) { return _InterlockedXor64_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedXor64_acq(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedXor64_acq(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i64 %mask acquire, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1191,7 +1191,7 @@ __int64 test_InterlockedXor64_acq(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedXor64_rel(__int64 volatile *value, __int64 mask) { return _InterlockedXor64_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedXor64_rel(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedXor64_rel(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i64 %mask release, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1199,7 +1199,7 @@ __int64 test_InterlockedXor64_rel(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedXor64_nf(__int64 volatile *value, __int64 mask) { return _InterlockedXor64_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedXor64_nf(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedXor64_nf(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw xor ptr %value, i64 %mask monotonic, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1207,7 +1207,7 @@ __int64 test_InterlockedXor64_nf(__int64 volatile *value, __int64 mask) { char test_InterlockedAnd8_acq(char volatile *value, char mask) { return _InterlockedAnd8_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedAnd8_acq(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedAnd8_acq(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i8 %mask acquire, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1215,7 +1215,7 @@ char test_InterlockedAnd8_acq(char volatile *value, char mask) { char test_InterlockedAnd8_rel(char volatile *value, char mask) { return _InterlockedAnd8_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedAnd8_rel(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedAnd8_rel(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i8 %mask release, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1223,7 +1223,7 @@ char test_InterlockedAnd8_rel(char volatile *value, char mask) { char test_InterlockedAnd8_nf(char volatile *value, char mask) { return _InterlockedAnd8_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedAnd8_nf(ptr{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedAnd8_nf(ptr{{.*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i8 %mask monotonic, align 1 // CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1231,7 +1231,7 @@ char test_InterlockedAnd8_nf(char volatile *value, char mask) { short test_InterlockedAnd16_acq(short volatile *value, short mask) { return _InterlockedAnd16_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedAnd16_acq(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedAnd16_acq(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i16 %mask acquire, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1239,7 +1239,7 @@ short test_InterlockedAnd16_acq(short volatile *value, short mask) { short test_InterlockedAnd16_rel(short volatile *value, short mask) { return _InterlockedAnd16_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedAnd16_rel(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedAnd16_rel(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i16 %mask release, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1247,7 +1247,7 @@ short test_InterlockedAnd16_rel(short volatile *value, short mask) { short test_InterlockedAnd16_nf(short volatile *value, short mask) { return _InterlockedAnd16_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedAnd16_nf(ptr{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedAnd16_nf(ptr{{.*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i16 %mask monotonic, align 2 // CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1255,7 +1255,7 @@ short test_InterlockedAnd16_nf(short volatile *value, short mask) { long test_InterlockedAnd_acq(long volatile *value, long mask) { return _InterlockedAnd_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAnd_acq(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAnd_acq(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i32 %mask acquire, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1263,7 +1263,7 @@ long test_InterlockedAnd_acq(long volatile *value, long mask) { long test_InterlockedAnd_rel(long volatile *value, long mask) { return _InterlockedAnd_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAnd_rel(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAnd_rel(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i32 %mask release, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1271,7 +1271,7 @@ long test_InterlockedAnd_rel(long volatile *value, long mask) { long test_InterlockedAnd_nf(long volatile *value, long mask) { return _InterlockedAnd_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAnd_nf(ptr{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedAnd_nf(ptr{{.*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i32 %mask monotonic, align 4 // CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1279,7 +1279,7 @@ long test_InterlockedAnd_nf(long volatile *value, long mask) { __int64 test_InterlockedAnd64_acq(__int64 volatile *value, __int64 mask) { return _InterlockedAnd64_acq(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAnd64_acq(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAnd64_acq(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i64 %mask acquire, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1287,7 +1287,7 @@ __int64 test_InterlockedAnd64_acq(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedAnd64_rel(__int64 volatile *value, __int64 mask) { return _InterlockedAnd64_rel(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAnd64_rel(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAnd64_rel(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i64 %mask release, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1295,7 +1295,7 @@ __int64 test_InterlockedAnd64_rel(__int64 volatile *value, __int64 mask) { __int64 test_InterlockedAnd64_nf(__int64 volatile *value, __int64 mask) { return _InterlockedAnd64_nf(value, mask); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAnd64_nf(ptr{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAnd64_nf(ptr{{.*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw and ptr %value, i64 %mask monotonic, align 8 // CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] // CHECK-ARM-ARM64: } @@ -1303,7 +1303,7 @@ __int64 test_InterlockedAnd64_nf(__int64 volatile *value, __int64 mask) { short test_InterlockedIncrement16_acq(short volatile *Addend) { return _InterlockedIncrement16_acq(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedIncrement16_acq(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedIncrement16_acq(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i16 1 acquire, align 2 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], 1 // CHECK-ARM-ARM64: ret i16 [[RESULT]] @@ -1312,7 +1312,7 @@ short test_InterlockedIncrement16_acq(short volatile *Addend) { short test_InterlockedIncrement16_rel(short volatile *Addend) { return _InterlockedIncrement16_rel(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedIncrement16_rel(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedIncrement16_rel(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i16 1 release, align 2 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], 1 // CHECK-ARM-ARM64: ret i16 [[RESULT]] @@ -1321,7 +1321,7 @@ short test_InterlockedIncrement16_rel(short volatile *Addend) { short test_InterlockedIncrement16_nf(short volatile *Addend) { return _InterlockedIncrement16_nf(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedIncrement16_nf(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedIncrement16_nf(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i16 1 monotonic, align 2 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], 1 // CHECK-ARM-ARM64: ret i16 [[RESULT]] @@ -1330,7 +1330,7 @@ short test_InterlockedIncrement16_nf(short volatile *Addend) { long test_InterlockedIncrement_acq(long volatile *Addend) { return _InterlockedIncrement_acq(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedIncrement_acq(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedIncrement_acq(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i32 1 acquire, align 4 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 // CHECK-ARM-ARM64: ret i32 [[RESULT]] @@ -1339,7 +1339,7 @@ long test_InterlockedIncrement_acq(long volatile *Addend) { long test_InterlockedIncrement_rel(long volatile *Addend) { return _InterlockedIncrement_rel(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedIncrement_rel(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedIncrement_rel(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i32 1 release, align 4 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 // CHECK-ARM-ARM64: ret i32 [[RESULT]] @@ -1348,7 +1348,7 @@ long test_InterlockedIncrement_rel(long volatile *Addend) { long test_InterlockedIncrement_nf(long volatile *Addend) { return _InterlockedIncrement_nf(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedIncrement_nf(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedIncrement_nf(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i32 1 monotonic, align 4 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 // CHECK-ARM-ARM64: ret i32 [[RESULT]] @@ -1357,7 +1357,7 @@ long test_InterlockedIncrement_nf(long volatile *Addend) { __int64 test_InterlockedIncrement64_acq(__int64 volatile *Addend) { return _InterlockedIncrement64_acq(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedIncrement64_acq(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedIncrement64_acq(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i64 1 acquire, align 8 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1 // CHECK-ARM-ARM64: ret i64 [[RESULT]] @@ -1366,7 +1366,7 @@ __int64 test_InterlockedIncrement64_acq(__int64 volatile *Addend) { __int64 test_InterlockedIncrement64_rel(__int64 volatile *Addend) { return _InterlockedIncrement64_rel(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedIncrement64_rel(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedIncrement64_rel(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i64 1 release, align 8 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1 // CHECK-ARM-ARM64: ret i64 [[RESULT]] @@ -1375,7 +1375,7 @@ __int64 test_InterlockedIncrement64_rel(__int64 volatile *Addend) { __int64 test_InterlockedIncrement64_nf(__int64 volatile *Addend) { return _InterlockedIncrement64_nf(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedIncrement64_nf(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedIncrement64_nf(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw add ptr %Addend, i64 1 monotonic, align 8 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1 // CHECK-ARM-ARM64: ret i64 [[RESULT]] @@ -1384,7 +1384,7 @@ __int64 test_InterlockedIncrement64_nf(__int64 volatile *Addend) { short test_InterlockedDecrement16_acq(short volatile *Addend) { return _InterlockedDecrement16_acq(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedDecrement16_acq(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedDecrement16_acq(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i16 1 acquire, align 2 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], -1 // CHECK-ARM-ARM64: ret i16 [[RESULT]] @@ -1393,7 +1393,7 @@ short test_InterlockedDecrement16_acq(short volatile *Addend) { short test_InterlockedDecrement16_rel(short volatile *Addend) { return _InterlockedDecrement16_rel(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedDecrement16_rel(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedDecrement16_rel(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i16 1 release, align 2 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], -1 // CHECK-ARM-ARM64: ret i16 [[RESULT]] @@ -1402,7 +1402,7 @@ short test_InterlockedDecrement16_rel(short volatile *Addend) { short test_InterlockedDecrement16_nf(short volatile *Addend) { return _InterlockedDecrement16_nf(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedDecrement16_nf(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedDecrement16_nf(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i16 1 monotonic, align 2 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i16 [[TMP]], -1 // CHECK-ARM-ARM64: ret i16 [[RESULT]] @@ -1411,7 +1411,7 @@ short test_InterlockedDecrement16_nf(short volatile *Addend) { long test_InterlockedDecrement_acq(long volatile *Addend) { return _InterlockedDecrement_acq(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedDecrement_acq(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedDecrement_acq(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i32 1 acquire, align 4 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 // CHECK-ARM-ARM64: ret i32 [[RESULT]] @@ -1420,7 +1420,7 @@ long test_InterlockedDecrement_acq(long volatile *Addend) { long test_InterlockedDecrement_rel(long volatile *Addend) { return _InterlockedDecrement_rel(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedDecrement_rel(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedDecrement_rel(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i32 1 release, align 4 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 // CHECK-ARM-ARM64: ret i32 [[RESULT]] @@ -1429,7 +1429,7 @@ long test_InterlockedDecrement_rel(long volatile *Addend) { long test_InterlockedDecrement_nf(long volatile *Addend) { return _InterlockedDecrement_nf(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedDecrement_nf(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedDecrement_nf(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i32 1 monotonic, align 4 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 // CHECK-ARM-ARM64: ret i32 [[RESULT]] @@ -1438,7 +1438,7 @@ long test_InterlockedDecrement_nf(long volatile *Addend) { __int64 test_InterlockedDecrement64_acq(__int64 volatile *Addend) { return _InterlockedDecrement64_acq(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedDecrement64_acq(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedDecrement64_acq(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i64 1 acquire, align 8 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1 // CHECK-ARM-ARM64: ret i64 [[RESULT]] @@ -1447,7 +1447,7 @@ __int64 test_InterlockedDecrement64_acq(__int64 volatile *Addend) { __int64 test_InterlockedDecrement64_rel(__int64 volatile *Addend) { return _InterlockedDecrement64_rel(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedDecrement64_rel(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedDecrement64_rel(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i64 1 release, align 8 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1 // CHECK-ARM-ARM64: ret i64 [[RESULT]] @@ -1456,7 +1456,7 @@ __int64 test_InterlockedDecrement64_rel(__int64 volatile *Addend) { __int64 test_InterlockedDecrement64_nf(__int64 volatile *Addend) { return _InterlockedDecrement64_nf(Addend); } -// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedDecrement64_nf(ptr{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedDecrement64_nf(ptr{{.*}}%Addend){{.*}}{ // CHECK-ARM-ARM64: [[TMP:%[0-9]+]] = atomicrmw sub ptr %Addend, i64 1 monotonic, align 8 // CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1 // CHECK-ARM-ARM64: ret i64 [[RESULT]] diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c index da0c809148018..fd2fdce31b52f 100644 --- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c +++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c @@ -95,3 +95,20 @@ __attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) { // CHECK: attributes #[[ATTR3]] = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } // CHECK: attributes #[[ATTR4:[0-9]+]] = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } //. +// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} +// CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} +// CHECK: [[META2]] = !{!"sanmd_covered2!C", [[META3:![0-9]+]]} +// CHECK: [[META3]] = !{i64 0} +// CHECK: [[META4]] = !{!"sanmd_covered2!C", [[META5:![0-9]+]]} +// CHECK: [[META5]] = !{i64 3} +// CHECK: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} +// CHECK: [[META7]] = !{!"p1 int", [[META8:![0-9]+]], i64 0} +// CHECK: [[META8]] = !{!"any pointer", [[META9:![0-9]+]], i64 0} +// CHECK: [[META9]] = !{!"omnipotent char", [[META10:![0-9]+]], i64 0} +// CHECK: [[META10]] = !{!"Simple C/C++ TBAA"} +// CHECK: [[META11]] = !{!"sanmd_atomics2!C"} +// CHECK: [[TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0} +// CHECK: [[META13]] = !{!"int", [[META9]], i64 0} +// CHECK: [[META14]] = !{!"sanmd_covered2!C", [[META15:![0-9]+]]} +// CHECK: [[META15]] = !{i64 2} +//. diff --git a/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp b/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp index 4aa79a28dd7d3..855787731c8b0 100644 --- a/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp +++ b/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp @@ -34,21 +34,21 @@ template static Y second(...) { extern "C" { // CHECK-LABEL: define {{[^@]+}}@first_pair_i32 -// CHECK-SAME: (i32 noundef returned [[X:%.*]], i32 noundef [[Y:%.*]]) +// CHECK-SAME: (i32 noundef returned [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[X]] // int first_pair_i32(int x, int y) { return first(x, y); } // CHECK-LABEL: define {{[^@]+}}@second_pair_i32 -// CHECK-SAME: (i32 noundef [[X:%.*]], i32 noundef returned [[Y:%.*]]) +// CHECK-SAME: (i32 noundef [[X:%.*]], i32 noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[Y]] // int second_pair_i32(int x, int y) { return second(x, y); } // CHECK-LABEL: define {{[^@]+}}@first_pair_f64 -// CHECK-SAME: (double noundef returned [[X:%.*]], double noundef [[Y:%.*]]) +// CHECK-SAME: (double noundef returned [[X:%.*]], double noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret double [[X]] // @@ -57,7 +57,7 @@ double first_pair_f64(double x, double y) { } // CHECK-LABEL: define {{[^@]+}}@second_pair_f64 -// CHECK-SAME: (double noundef [[X:%.*]], double noundef returned [[Y:%.*]]) +// CHECK-SAME: (double noundef [[X:%.*]], double noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret double [[Y]] // @@ -69,28 +69,28 @@ double second_pair_f64(double x, double y) { extern "C" { // CHECK-LABEL: define {{[^@]+}}@first_i32_f64 -// CHECK-SAME: (i32 noundef returned [[X:%.*]], double noundef [[Y:%.*]]) +// CHECK-SAME: (i32 noundef returned [[X:%.*]], double noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[X]] // int first_i32_f64(int x, double y) { return first(x, y); } // CHECK-LABEL: define {{[^@]+}}@second_i32_f64 -// CHECK-SAME: (i32 noundef [[X:%.*]], double noundef returned [[Y:%.*]]) +// CHECK-SAME: (i32 noundef [[X:%.*]], double noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret double [[Y]] // double second_i32_f64(int x, double y) { return second(x, y); } // CHECK-LABEL: define {{[^@]+}}@first_f64_i32 -// CHECK-SAME: (double noundef returned [[X:%.*]], i32 noundef [[Y:%.*]]) +// CHECK-SAME: (double noundef returned [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret double [[X]] // double first_f64_i32(double x, int y) { return first(x, y); } // CHECK-LABEL: define {{[^@]+}}@second_f64_i32 -// CHECK-SAME: (double noundef [[X:%.*]], i32 noundef returned [[Y:%.*]]) +// CHECK-SAME: (double noundef [[X:%.*]], i32 noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[Y]] // @@ -101,7 +101,7 @@ extern "C" { typedef uint64_t ulong2 __attribute__((__vector_size__(16), __aligned__(16))); // CHECK-LABEL: define {{[^@]+}}@first_i32_ulong2 -// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) +// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[X]] // @@ -130,7 +130,7 @@ void first_ulong2_i32(ulong2 *x, int y, ulong2 *r) { } // CHECK-LABEL: define {{[^@]+}}@second_ulong2_i32 -// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) +// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[Y]] // @@ -150,7 +150,7 @@ typedef struct { extern "C" { // CHECK-LABEL: define {{[^@]+}}@first_i32_asc -// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) +// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[X]] // @@ -173,7 +173,7 @@ void second_i32_asc(int x, asc *y, asc *r) { *r = second(x, *y); } void first_asc_i32(asc *x, int y, asc *r) { *r = first(*x, y); } // CHECK-LABEL: define {{[^@]+}}@second_asc_i32 -// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) +// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[Y]] // diff --git a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp index 2257a4c2d975a..69572bea3664a 100644 --- a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp +++ b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp @@ -7,6 +7,8 @@ struct identity { using type = T; }; +template using ElementType = int; + template void f() { static_assert([](Is... x) { @@ -47,6 +49,10 @@ template void f() { }(), ...); }(1, 2); + [](Is...) { + ([] { using T = ElementType; }(), ...); + }(1); + [](auto ...y) { ([y] { }(), ...); }(); diff --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp index 45332fd15b5d4..bfb808773b900 100644 --- a/clang/test/SemaCXX/reinterpret-cast.cpp +++ b/clang/test/SemaCXX/reinterpret-cast.cpp @@ -302,3 +302,77 @@ void reinterpret_cast_allowlist () { (void)reinterpret_cast(b); (void)*reinterpret_cast(&b); } + +namespace templated { +template +void cast_uninstantiated() { + const UATYPE* data; + (void)*reinterpret_cast(data); // no warning +} + + +template +void cast_instantiated_badly() { + const UATYPE* data; + (void)*reinterpret_cast(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}} +} + +template +void cast_instantiated_well() { + const UATYPE* data; + (void)*reinterpret_cast(data); // no warning +} + +template +void cast_one_tmpl_arg_uninstantiated() { + const int* data; + (void)*reinterpret_cast(data); // no warning +} + +template +void cast_one_tmpl_arg_instantiated_badly() { + const float* data; + (void)*reinterpret_cast(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}} +} + +template +void cast_one_tmpl_arg_instantiated_well() { + const float* data; + (void)*reinterpret_cast(data); // no warning +} + +template +void cast_nontype_template_true_positive_noninstantiated() { + const float *data; + const int arr[size]; + (void)*reinterpret_cast(data); // expected-warning {{dereference of type 'const int *' that was reinterpret_cast from type 'const float *' has undefined behavior}} +} + +template +void cast_nontype_template_true_negative_noninstantiated() { + const int data[size]; + (void)*reinterpret_cast(data); // no warning +} + +void top() { + cast_instantiated_badly(); + // expected-note@-1 {{in instantiation of function template specialization 'templated::cast_instantiated_badly' requested here}} + cast_instantiated_well(); + cast_one_tmpl_arg_instantiated_badly(); + // expected-note@-1 {{in instantiation of function template specialization 'templated::cast_one_tmpl_arg_instantiated_badly' requested here}} + cast_one_tmpl_arg_instantiated_well(); +} + +template +void cast_template_dependent_type_noninstantiated(T** x) +{ + (void)*reinterpret_cast(x); +} + +template +void cast_template_dependent_member_type_noninstantiated(typename T::X x) +{ + (void)*reinterpret_cast(x); +} + +} // namespace templated diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp index 7a1a47a78dbc6..0841161ee5c42 100644 --- a/compiler-rt/lib/interception/interception_win.cpp +++ b/compiler-rt/lib/interception/interception_win.cpp @@ -651,6 +651,10 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0xD284: // 84 D2 : test dl,dl return 2; + case 0x3980: // 80 39 XX : cmp BYTE PTR [rcx], XX + case 0x4D8B: // 8B 4D XX : mov XX(%ebp), ecx + case 0x558B: // 8B 55 XX : mov XX(%ebp), edx + case 0x758B: // 8B 75 XX : mov XX(%ebp), esp case 0xE483: // 83 E4 XX : and esp, XX case 0xEC83: // 83 EC XX : sub esp, XX case 0xC1F6: // F6 C1 XX : test cl, XX @@ -757,6 +761,9 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0xc1ff48: // 48 ff c1 : inc rcx case 0xc1ff49: // 49 ff c1 : inc r9 case 0xc28b41: // 41 8b c2 : mov eax, r10d + case 0x01b60f: // 0f b6 01 : movzx eax, BYTE PTR [rcx] + case 0x09b60f: // 0f b6 09 : movzx ecx, BYTE PTR [rcx] + case 0x11b60f: // 0f b6 11 : movzx edx, BYTE PTR [rcx] case 0xc2b60f: // 0f b6 c2 : movzx eax, dl case 0xc2ff48: // 48 ff c2 : inc rdx case 0xc2ff49: // 49 ff c2 : inc r10 @@ -775,6 +782,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0xc98548: // 48 85 c9 : test rcx, rcx case 0xc9854d: // 4d 85 c9 : test r9, r9 case 0xc98b4c: // 4c 8b c9 : mov r9, rcx + case 0xd12948: // 48 29 d1 : sub rcx, rdx case 0xca2b48: // 48 2b ca : sub rcx, rdx case 0xca3b48: // 48 3b ca : cmp rcx, rdx case 0xd12b48: // 48 2b d1 : sub rdx, rcx @@ -784,16 +792,33 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0xd2854d: // 4d 85 d2 : test r10, r10 case 0xd28b4c: // 4c 8b d2 : mov r10, rdx case 0xd2b60f: // 0f b6 d2 : movzx edx, dl + case 0xd2be0f: // 0f be d2 : movsx edx, dl case 0xd98b4c: // 4c 8b d9 : mov r11, rcx case 0xd9f748: // 48 f7 d9 : neg rcx + case 0xc03145: // 45 31 c0 : xor r8d,r8d + case 0xc93145: // 45 31 c9 : xor r9d,r9d case 0xdb3345: // 45 33 db : xor r11d, r11d + case 0xc08445: // 45 84 c0 : test r8b,r8b + case 0xd28445: // 45 84 d2 : test r10b,r10b case 0xdb8548: // 48 85 db : test rbx, rbx case 0xdb854d: // 4d 85 db : test r11, r11 case 0xdc8b4c: // 4c 8b dc : mov r11, rsp case 0xe48548: // 48 85 e4 : test rsp, rsp case 0xe4854d: // 4d 85 e4 : test r12, r12 + case 0xc88948: // 48 89 c8 : mov rax,rcx + case 0xcb8948: // 48 89 cb : mov rbx,rcx + case 0xd08948: // 48 89 d0 : mov rax,rdx + case 0xd18948: // 48 89 d1 : mov rcx,rdx + case 0xd38948: // 48 89 d3 : mov rbx,rdx case 0xe58948: // 48 89 e5 : mov rbp, rsp case 0xed8548: // 48 85 ed : test rbp, rbp + case 0xc88949: // 49 89 c8 : mov r8, rcx + case 0xc98949: // 49 89 c9 : mov r9, rcx + case 0xca8949: // 49 89 ca : mov r10,rcx + case 0xd08949: // 49 89 d0 : mov r8, rdx + case 0xd18949: // 49 89 d1 : mov r9, rdx + case 0xd28949: // 49 89 d2 : mov r10, rdx + case 0xd38949: // 49 89 d3 : mov r11, rdx case 0xed854d: // 4d 85 ed : test r13, r13 case 0xf6854d: // 4d 85 f6 : test r14, r14 case 0xff854d: // 4d 85 ff : test r15, r15 diff --git a/compiler-rt/lib/interception/tests/interception_win_test.cpp b/compiler-rt/lib/interception/tests/interception_win_test.cpp index e0258a3d0bd51..9d8dbfcb4285f 100644 --- a/compiler-rt/lib/interception/tests/interception_win_test.cpp +++ b/compiler-rt/lib/interception/tests/interception_win_test.cpp @@ -857,8 +857,12 @@ const struct InstructionSizeData { { 2, {0x8B, 0xC1}, 0, "8B C1 : mov eax, ecx"}, { 2, {0x8B, 0xEC}, 0, "8B EC : mov ebp, esp"}, { 2, {0x8B, 0xFF}, 0, "8B FF : mov edi, edi"}, + { 3, {0x80, 0x39, 0x72}, 0, "80 39 XX : cmp BYTE PTR [rcx], XX"}, { 3, {0x83, 0xE4, 0x72}, 0, "83 E4 XX : and esp, XX"}, { 3, {0x83, 0xEC, 0x72}, 0, "83 EC XX : sub esp, XX"}, + { 3, {0x8B, 0x4D, 0x72}, 0, "8B 4D XX : mov XX(%ebp), ecx"}, + { 3, {0x8B, 0x55, 0x72}, 0, "8B 55 XX : mov XX(%ebp), edx"}, + { 3, {0x8B, 0x75, 0x72}, 0, "8B 75 XX : mov XX(%ebp), esp"}, { 3, {0xc2, 0x71, 0x72}, 0, "C2 XX XX : ret XX (needed for registering weak functions)"}, { 5, {0x68, 0x71, 0x72, 0x73, 0x74}, 0, "68 XX XX XX XX : push imm32"}, { 5, {0xb8, 0x71, 0x72, 0x73, 0x74}, 0, "b8 XX XX XX XX : mov eax, XX XX XX XX"}, @@ -881,17 +885,26 @@ const struct InstructionSizeData { { 2, {0x66, 0x90}, 0, "66 90 : Two-byte NOP"}, { 2, {0x84, 0xc0}, 0, "84 c0 : test al, al"}, { 2, {0x8a, 0x01}, 0, "8a 01 : mov al, byte ptr [rcx]"}, + { 3, {0x0f, 0xb6, 0x01}, 0, "0f b6 01 : movzx eax, BYTE PTR [rcx]"}, + { 3, {0x0f, 0xb6, 0x09}, 0, "0f b6 09 : movzx ecx, BYTE PTR [rcx]"}, + { 3, {0x0f, 0xb6, 0x11}, 0, "0f b6 11 : movzx edx, BYTE PTR [rcx]"}, { 3, {0x0f, 0xb6, 0xc2}, 0, "0f b6 c2 : movzx eax, dl"}, { 3, {0x0f, 0xb6, 0xd2}, 0, "0f b6 d2 : movzx edx, dl"}, { 3, {0x0f, 0xb7, 0x10}, 0, "0f b7 10 : movzx edx, WORD PTR [rax]"}, + { 3, {0x0f, 0xbe, 0xd2}, 0, "0f be d2 : movsx edx, dl"}, { 3, {0x41, 0x8b, 0xc0}, 0, "41 8b c0 : mov eax, r8d"}, { 3, {0x41, 0x8b, 0xc1}, 0, "41 8b c1 : mov eax, r9d"}, { 3, {0x41, 0x8b, 0xc2}, 0, "41 8b c2 : mov eax, r10d"}, { 3, {0x41, 0x8b, 0xc3}, 0, "41 8b c3 : mov eax, r11d"}, { 3, {0x41, 0x8b, 0xc4}, 0, "41 8b c4 : mov eax, r12d"}, + { 3, {0x45, 0x31, 0xc0}, 0, "45 31 c0 : xor r8d,r8d"}, + { 3, {0x45, 0x31, 0xc9}, 0, "45 31 c9 : xor r9d,r9d"}, { 3, {0x45, 0x33, 0xc0}, 0, "45 33 c0 : xor r8d, r8d"}, { 3, {0x45, 0x33, 0xc9}, 0, "45 33 c9 : xor r9d, r9d"}, { 3, {0x45, 0x33, 0xdb}, 0, "45 33 db : xor r11d, r11d"}, + { 3, {0x45, 0x84, 0xc0}, 0, "45 84 c0 : test r8b,r8b"}, + { 3, {0x45, 0x84, 0xd2}, 0, "45 84 d2 : test r10b,r10b"}, + { 3, {0x48, 0x29, 0xd1}, 0, "48 29 d1 : sub rcx, rdx"}, { 3, {0x48, 0x2b, 0xca}, 0, "48 2b ca : sub rcx, rdx"}, { 3, {0x48, 0x2b, 0xd1}, 0, "48 2b d1 : sub rdx, rcx"}, { 3, {0x48, 0x3b, 0xca}, 0, "48 3b ca : cmp rcx, rdx"}, @@ -901,6 +914,11 @@ const struct InstructionSizeData { { 3, {0x48, 0x85, 0xdb}, 0, "48 85 db : test rbx, rbx"}, { 3, {0x48, 0x85, 0xe4}, 0, "48 85 e4 : test rsp, rsp"}, { 3, {0x48, 0x85, 0xed}, 0, "48 85 ed : test rbp, rbp"}, + { 3, {0x48, 0x89, 0xc8}, 0, "48 89 c8 : mov rax,rcx"}, + { 3, {0x48, 0x89, 0xcb}, 0, "48 89 cb : mov rbx,rcx"}, + { 3, {0x48, 0x89, 0xd0}, 0, "48 89 d0 : mov rax,rdx"}, + { 3, {0x48, 0x89, 0xd1}, 0, "48 89 d1 : mov rcx,rdx"}, + { 3, {0x48, 0x89, 0xd3}, 0, "48 89 d3 : mov rbx,rdx"}, { 3, {0x48, 0x89, 0xe5}, 0, "48 89 e5 : mov rbp, rsp"}, { 3, {0x48, 0x8b, 0xc1}, 0, "48 8b c1 : mov rax, rcx"}, { 3, {0x48, 0x8b, 0xc4}, 0, "48 8b c4 : mov rax, rsp"}, @@ -912,6 +930,13 @@ const struct InstructionSizeData { { 3, {0x48, 0xff, 0xc3}, 0, "48 ff c3 : inc rbx"}, { 3, {0x48, 0xff, 0xc6}, 0, "48 ff c6 : inc rsi"}, { 3, {0x48, 0xff, 0xc7}, 0, "48 ff c7 : inc rdi"}, + { 3, {0x49, 0x89, 0xc8}, 0, "49 89 c8 : mov r8, rcx"}, + { 3, {0x49, 0x89, 0xc9}, 0, "49 89 c9 : mov r9, rcx"}, + { 3, {0x49, 0x89, 0xca}, 0, "49 89 ca : mov r10,rcx"}, + { 3, {0x49, 0x89, 0xd0}, 0, "49 89 d0 : mov r8, rdx"}, + { 3, {0x49, 0x89, 0xd1}, 0, "49 89 d1 : mov r9, rdx"}, + { 3, {0x49, 0x89, 0xd2}, 0, "49 89 d2 : mov r10, rdx"}, + { 3, {0x49, 0x89, 0xd3}, 0, "49 89 d3 : mov r11, rdx"}, { 3, {0x49, 0xff, 0xc0}, 0, "49 ff c0 : inc r8"}, { 3, {0x49, 0xff, 0xc1}, 0, "49 ff c1 : inc r9"}, { 3, {0x49, 0xff, 0xc2}, 0, "49 ff c2 : inc r10"}, diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp index d8ce231d1b5a7..0b57a10a6c493 100644 --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -210,6 +210,7 @@ mlir::Type getDerivedType(mlir::Type ty) { return seq.getEleTy(); return p.getEleTy(); }) + .Case([](auto p) { return getDerivedType(p.getEleTy()); }) .Default([](mlir::Type t) { return t; }); } diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp index 8ae3d313d881c..555f354521c9b 100644 --- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp +++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp @@ -258,70 +258,6 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType( dataLocation, /*rank=*/nullptr, allocated, associated); } -// If the type is a pointer or array type then gets its underlying type. -static mlir::LLVM::DITypeAttr getUnderlyingType(mlir::LLVM::DITypeAttr Ty) { - if (auto ptrTy = - mlir::dyn_cast_if_present(Ty)) { - if (ptrTy.getTag() == llvm::dwarf::DW_TAG_pointer_type) - Ty = getUnderlyingType(ptrTy.getBaseType()); - } - if (auto comTy = - mlir::dyn_cast_if_present(Ty)) { - if (comTy.getTag() == llvm::dwarf::DW_TAG_array_type) - Ty = getUnderlyingType(comTy.getBaseType()); - } - return Ty; -} - -// Currently, the handling of recursive debug type in mlir has some limitations. -// Those limitations were discussed at the end of the thread for following PR. -// https://github.com/llvm/llvm-project/pull/106571 -// -// Problem could be explained with the following example code: -// type t2 -// type(t1), pointer :: p1 -// end type -// type t1 -// type(t2), pointer :: p2 -// end type -// In the description below, type_self means a temporary type that is generated -// as a place holder while the members of that type are being processed. -// -// If we process t1 first then we will have the following structure after it has -// been processed. -// t1 -> t2 -> t1_self -// This is because when we started processing t2, we did not have the complete -// t1 but its place holder t1_self. -// Now if some entity requires t2, we will already have that in cache and will -// return it. But this t2 refers to t1_self and not to t1. In mlir handling, -// only those types are allowed to have _self reference which are wrapped by -// entity whose reference it is. So t1 -> t2 -> t1_self is ok because the -// t1_self reference can be resolved by the outer t1. But standalone t2 is not -// because there will be no way to resolve it. Until this is fixed in mlir, we -// avoid caching such types. Please see DebugTranslation::translateRecursive for -// details on how mlir handles recursive types. -static bool canCacheThisType(mlir::LLVM::DICompositeTypeAttr comTy) { - for (auto el : comTy.getElements()) { - if (auto mem = - mlir::dyn_cast_if_present(el)) { - mlir::LLVM::DITypeAttr memTy = getUnderlyingType(mem.getBaseType()); - if (auto baseTy = - mlir::dyn_cast_if_present( - memTy)) { - // We will not cache a type if one of its member meets the following - // conditions: - // 1. It is a structure type - // 2. It is a place holder type (getIsRecSelf() is true) - // 3. It is not a self reference. It is ok to have t1_self in t1. - if (baseTy.getTag() == llvm::dwarf::DW_TAG_structure_type && - baseTy.getIsRecSelf() && (comTy.getRecId() != baseTy.getRecId())) - return false; - } - } - } - return true; -} - std::pair DebugTypeGenerator::getFieldSizeAndAlign(mlir::Type fieldTy) { mlir::Type llvmTy; @@ -343,6 +279,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType( if (iter != typeCache.end()) return iter->second; + bool canCacheThisType = true; llvm::SmallVector elements; mlir::MLIRContext *context = module.getContext(); auto recId = mlir::DistinctAttr::create(mlir::UnitAttr::get(context)); @@ -406,6 +343,62 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType( /*extra data=*/nullptr); elements.push_back(tyAttr); offset += llvm::alignTo(byteSize, byteAlign); + + // Currently, the handling of recursive debug type in mlir has some + // limitations that were discussed at the end of the thread for following + // PR. + // https://github.com/llvm/llvm-project/pull/106571 + // + // Problem could be explained with the following example code: + // type t2 + // type(t1), pointer :: p1 + // end type + // type t1 + // type(t2), pointer :: p2 + // end type + // In the description below, type_self means a temporary type that is + // generated + // as a place holder while the members of that type are being processed. + // + // If we process t1 first then we will have the following structure after + // it has been processed. + // t1 -> t2 -> t1_self + // This is because when we started processing t2, we did not have the + // complete t1 but its place holder t1_self. + // Now if some entity requires t2, we will already have that in cache and + // will return it. But this t2 refers to t1_self and not to t1. In mlir + // handling, only those types are allowed to have _self reference which are + // wrapped by entity whose reference it is. So t1 -> t2 -> t1_self is ok + // because the t1_self reference can be resolved by the outer t1. But + // standalone t2 is not because there will be no way to resolve it. Until + // this is fixed in mlir, we avoid caching such types. Please see + // DebugTranslation::translateRecursive for details on how mlir handles + // recursive types. + // The code below checks for situation where it will be unsafe to cache + // a type to avoid this problem. We do that in 2 situations. + // 1. If a member is record type, then its type would have been processed + // before reaching here. If it is not in the cache, it means that it was + // found to be unsafe to cache. So any type containing it will also not + // be cached + // 2. The type of the member is found in the cache but it is a place holder. + // In this case, its recID should match the recID of the type we are + // processing. This helps us to cache the following type. + // type t + // type(t), allocatable :: p + // end type + mlir::Type baseTy = getDerivedType(fieldTy); + if (auto recTy = mlir::dyn_cast(baseTy)) { + auto iter = typeCache.find(recTy); + if (iter == typeCache.end()) + canCacheThisType = false; + else { + if (auto tyAttr = + mlir::dyn_cast(iter->second)) { + if (tyAttr.getIsRecSelf() && tyAttr.getRecId() != recId) + canCacheThisType = false; + } + } + } } auto finalAttr = mlir::LLVM::DICompositeTypeAttr::get( @@ -414,7 +407,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType( /*baseType=*/nullptr, mlir::LLVM::DIFlags::Zero, offset * 8, /*alignInBits=*/0, elements, /*dataLocation=*/nullptr, /*rank=*/nullptr, /*allocated=*/nullptr, /*associated=*/nullptr); - if (canCacheThisType(finalAttr)) { + if (canCacheThisType) { typeCache[Ty] = finalAttr; } else { auto iter = typeCache.find(Ty); diff --git a/flang/test/Integration/debug-cyclic-derived-type-3.f90 b/flang/test/Integration/debug-cyclic-derived-type-3.f90 new file mode 100644 index 0000000000000..ef9aed13cc514 --- /dev/null +++ b/flang/test/Integration/debug-cyclic-derived-type-3.f90 @@ -0,0 +1,32 @@ +! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - + +! mainly test that this program does not cause an assertion failure +! testcase for issue 122024 + +module m1 + type t1 + type(t2),pointer :: x1 + end type + type t2 + type(t3),pointer :: x2 + end type + type t3 + type(t1),pointer :: x3 + end type +end + +program test + use m1 + type(t1),pointer :: foo + allocate(foo) + allocate(foo%x1) + allocate(foo%x1%x2) + allocate(foo%x1%x2%x3) + call sub1(foo%x1) + print *,'done' +end program + +subroutine sub1(bar) + use m1 + type(t2) :: bar +end subroutine diff --git a/flang/test/Lower/module_use.f90 b/flang/test/Lower/module_use.f90 index b976663239ef5..f7c610c9ad22e 100644 --- a/flang/test/Lower/module_use.f90 +++ b/flang/test/Lower/module_use.f90 @@ -1,6 +1,6 @@ -! RUN: rm -fr %t && mkdir -p %t -! RUN: bbc -emit-fir -module %t %S/module_definition.f90 -! RUN: bbc -emit-fir -J %t %s -o - | FileCheck %s +! RUN: rm -fr %t && mkdir -p %t && cd %t +! RUN: bbc -emit-fir %S/module_definition.f90 +! RUN: bbc -emit-fir %s -o - | FileCheck %s ! Test use of module data not defined in this file. ! The modules are defined in module_definition.f90 diff --git a/libclc/clc/include/clc/common/clc_degrees.h b/libclc/clc/include/clc/common/clc_degrees.h index e8bb684fcd4d7..617030aed4436 100644 --- a/libclc/clc/include/clc/common/clc_degrees.h +++ b/libclc/clc/include/clc/common/clc_degrees.h @@ -1,5 +1,5 @@ -#ifndef __CLC_MATH_CLC_DEGREES_H__ -#define __CLC_MATH_CLC_DEGREES_H__ +#ifndef __CLC_COMMON_CLC_DEGREES_H__ +#define __CLC_COMMON_CLC_DEGREES_H__ #define __CLC_BODY #define __CLC_FUNCTION __clc_degrees @@ -9,4 +9,4 @@ #undef __CLC_BODY #undef __CLC_FUNCTION -#endif // __CLC_MATH_CLC_DEGREES_H__ +#endif // __CLC_COMMON_CLC_DEGREES_H__ diff --git a/libclc/clc/include/clc/common/clc_radians.h b/libclc/clc/include/clc/common/clc_radians.h index 80d481e8de723..018a675cdc89a 100644 --- a/libclc/clc/include/clc/common/clc_radians.h +++ b/libclc/clc/include/clc/common/clc_radians.h @@ -1,5 +1,5 @@ -#ifndef __CLC_MATH_CLC_RADIANS_H__ -#define __CLC_MATH_CLC_RADIANS_H__ +#ifndef __CLC_COMMON_CLC_RADIANS_H__ +#define __CLC_COMMON_CLC_RADIANS_H__ #define __CLC_BODY #define __CLC_FUNCTION __clc_radians @@ -9,4 +9,4 @@ #undef __CLC_BODY #undef __CLC_FUNCTION -#endif // __CLC_MATH_CLC_RADIANS_H__ +#endif // __CLC_COMMON_CLC_RADIANS_H__ diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index 115e3457db697..ff3c89884c24d 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -1183,7 +1183,7 @@ size_t Arm64XDynamicRelocEntry::getSize() const { void Arm64XDynamicRelocEntry::writeTo(uint8_t *buf) const { auto out = reinterpret_cast(buf); - *out = (offset & 0xfff) | (type << 12); + *out = (offset.get() & 0xfff) | (type << 12); switch (type) { case IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE: @@ -1211,14 +1211,19 @@ void Arm64XDynamicRelocEntry::writeTo(uint8_t *buf) const { void DynamicRelocsChunk::finalize() { llvm::stable_sort(arm64xRelocs, [=](const Arm64XDynamicRelocEntry &a, const Arm64XDynamicRelocEntry &b) { - return a.offset < b.offset; + return a.offset.get() < b.offset.get(); }); - size = sizeof(coff_dynamic_reloc_table) + sizeof(coff_dynamic_relocation64) + - sizeof(coff_base_reloc_block_header); + size = sizeof(coff_dynamic_reloc_table) + sizeof(coff_dynamic_relocation64); + uint32_t prevPage = 0xfff; for (const Arm64XDynamicRelocEntry &entry : arm64xRelocs) { - assert(!(entry.offset & ~0xfff)); // Not yet supported. + uint32_t page = entry.offset.get() & ~0xfff; + if (page != prevPage) { + size = alignTo(size, sizeof(uint32_t)) + + sizeof(coff_base_reloc_block_header); + prevPage = page; + } size += entry.getSize(); } @@ -1235,17 +1240,31 @@ void DynamicRelocsChunk::writeTo(uint8_t *buf) const { header->Symbol = IMAGE_DYNAMIC_RELOCATION_ARM64X; buf += sizeof(*header); - auto pageHeader = reinterpret_cast(buf); - pageHeader->BlockSize = sizeof(*pageHeader); + coff_base_reloc_block_header *pageHeader = nullptr; + size_t relocSize = 0; for (const Arm64XDynamicRelocEntry &entry : arm64xRelocs) { - entry.writeTo(buf + pageHeader->BlockSize); - pageHeader->BlockSize += entry.getSize(); + uint32_t page = entry.offset.get() & ~0xfff; + if (!pageHeader || page != pageHeader->PageRVA) { + relocSize = alignTo(relocSize, sizeof(uint32_t)); + if (pageHeader) + pageHeader->BlockSize = + buf + relocSize - reinterpret_cast(pageHeader); + pageHeader = + reinterpret_cast(buf + relocSize); + pageHeader->PageRVA = page; + relocSize += sizeof(*pageHeader); + } + + entry.writeTo(buf + relocSize); + relocSize += entry.getSize(); } - pageHeader->BlockSize = alignTo(pageHeader->BlockSize, sizeof(uint32_t)); + relocSize = alignTo(relocSize, sizeof(uint32_t)); + pageHeader->BlockSize = + buf + relocSize - reinterpret_cast(pageHeader); - header->BaseRelocSize = pageHeader->BlockSize; - table->Size += header->BaseRelocSize; - assert(size == sizeof(*table) + sizeof(*header) + header->BaseRelocSize); + header->BaseRelocSize = relocSize; + table->Size += relocSize; + assert(size == sizeof(*table) + sizeof(*header) + relocSize); } } // namespace lld::coff diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h index 46fd8e21dce65..7ba58e336451f 100644 --- a/lld/COFF/Chunks.h +++ b/lld/COFF/Chunks.h @@ -851,13 +851,13 @@ class Arm64XRelocVal { class Arm64XDynamicRelocEntry { public: Arm64XDynamicRelocEntry(llvm::COFF::Arm64XFixupType type, uint8_t size, - uint32_t offset, Arm64XRelocVal value) + Arm64XRelocVal offset, Arm64XRelocVal value) : offset(offset), value(value), type(type), size(size) {} size_t getSize() const; void writeTo(uint8_t *buf) const; - uint32_t offset; + Arm64XRelocVal offset; Arm64XRelocVal value; private: @@ -873,8 +873,8 @@ class DynamicRelocsChunk : public NonSectionChunk { void writeTo(uint8_t *buf) const override; void finalize(); - void add(llvm::COFF::Arm64XFixupType type, uint8_t size, uint32_t offset, - Arm64XRelocVal value) { + void add(llvm::COFF::Arm64XFixupType type, uint8_t size, + Arm64XRelocVal offset, Arm64XRelocVal value) { arm64xRelocs.emplace_back(type, size, offset, value); } diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp index 148822fdb68ff..fce50d41a663b 100644 --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -100,7 +100,6 @@ bool Symbol::isLive() const { return true; } -// MinGW specific. void Symbol::replaceKeepingName(Symbol *other, size_t size) { StringRef origName = getName(); memcpy(this, other, size); diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 8247f131dcf07..536c1eef5e49c 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -2352,6 +2352,20 @@ void Writer::setECSymbols() { delayIatCopySym, "__hybrid_auxiliary_delayload_iat_copy", delayIdata.getAuxIatCopy().empty() ? nullptr : delayIdata.getAuxIatCopy().front()); + + if (ctx.hybridSymtab) { + // For the hybrid image, set the alternate entry point to the EC entry + // point. In the hybrid view, it is swapped to the native entry point + // using ARM64X relocations. + if (auto altEntrySym = cast_or_null(ctx.hybridSymtab->entry)) { + // If the entry is an EC export thunk, use its target instead. + if (auto thunkChunk = + dyn_cast(altEntrySym->getChunk())) + altEntrySym = thunkChunk->target; + symtab->findUnderscore("__arm64x_native_entrypoint") + ->replaceKeepingName(altEntrySym, sizeof(SymbolUnion)); + } + } } // Write section contents to a mmap'ed file. @@ -2586,12 +2600,23 @@ void Writer::createDynamicRelocs() { coffHeaderOffset + offsetof(coff_file_header, Machine), AMD64); - if (ctx.symtab.entry != ctx.hybridSymtab->entry) + if (ctx.symtab.entry != ctx.hybridSymtab->entry) { ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t), peHeaderOffset + offsetof(pe32plus_header, AddressOfEntryPoint), cast_or_null(ctx.hybridSymtab->entry)); + // Swap the alternate entry point in the CHPE metadata. + Symbol *s = ctx.hybridSymtab->findUnderscore("__chpe_metadata"); + if (auto chpeSym = cast_or_null(s)) + ctx.dynamicRelocs->add( + IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t), + Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, AlternateEntryPoint)), + cast_or_null(ctx.symtab.entry)); + else + Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target"; + } + // Set the hybrid load config to the EC load config. ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t), dataDirOffset64 + diff --git a/lld/test/COFF/arm64x-entry.test b/lld/test/COFF/arm64x-entry.test index d5363c66544a5..1c2e7e7a0c93a 100644 --- a/lld/test/COFF/arm64x-entry.test +++ b/lld/test/COFF/arm64x-entry.test @@ -3,12 +3,14 @@ RUN: split-file %s %t.dir && cd %t.dir RUN: llvm-mc -filetype=obj -triple=arm64ec-windows arm64ec-dllmain.s -o arm64ec-dllmain.obj RUN: llvm-mc -filetype=obj -triple=aarch64-windows arm64-dllmain.s -o arm64-dllmain.obj +RUN: llvm-mc -filetype=obj -triple=x86_64-windows amd64-dllmain.s -o amd64-dllmain.obj RUN: llvm-mc -filetype=obj -triple=arm64ec-windows arm64ec-func.s -o arm64ec-func.obj RUN: llvm-mc -filetype=obj -triple=aarch64-windows arm64-func.s -o arm64-func.obj RUN: llvm-mc -filetype=obj -triple=arm64ec-windows arm64-drectve.s -o arm64ec-drectve.obj RUN: llvm-mc -filetype=obj -triple=aarch64-windows arm64-drectve.s -o arm64-drectve.obj RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64.s -o loadconfig-arm64.obj +RUN: llvm-mc -filetype=obj -triple=arm64ec-windows loadconfig-min.s -o loadconfig-min.obj RUN: lld-link -machine:arm64x -dll -out:out.dll arm64ec-dllmain.obj arm64-dllmain.obj \ RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj @@ -34,10 +36,12 @@ DISASM-NEXT: 180003009: e9 f2 ef ff ff jmp 0x180002000 <.text+ DISASM-NEXT: 18000300e: cc int3 DISASM-NEXT: 18000300f: cc int3 -RUN: llvm-readobj --headers out.dll | FileCheck --check-prefix=READOBJ %s +RUN: llvm-readobj --headers --coff-load-config out.dll | FileCheck --check-prefix=READOBJ %s READOBJ: AddressOfEntryPoint: 0x1000 +READOBJ: AlternateEntryPoint: 0x2000 READOBJ: HybridObject { READOBJ: AddressOfEntryPoint: 0x3000 +READOBJ: AlternateEntryPoint: 0x1000 READOBJ: } RUN: lld-link -machine:arm64x -dll -out:out2.dll arm64ec-func.obj arm64-func.obj \ @@ -55,6 +59,20 @@ RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj -entry:func RUN: llvm-objdump -d out4.dll | FileCheck --check-prefix=DISASM %s RUN: llvm-readobj --headers --coff-load-config out4.dll | FileCheck --check-prefix=READOBJ %s +RUN: lld-link -machine:arm64x -dll -out:out-x86.dll amd64-dllmain.obj arm64-dllmain.obj \ +RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj +RUN: llvm-readobj --headers --coff-load-config out-x86.dll | FileCheck --check-prefix=READOBJ-X86 %s +READOBJ-X86: AddressOfEntryPoint: 0x1000 +READOBJ-X86: AlternateEntryPoint: 0x2000 +READOBJ-X86: HybridObject { +READOBJ-X86: AddressOfEntryPoint: 0x2000 +READOBJ-X86: AlternateEntryPoint: 0x1000 +READOBJ-X86: } + +RUN: lld-link -machine:arm64x -dll -out:out-warn.dll arm64ec-dllmain.obj arm64-dllmain.obj \ +RUN: loadconfig-arm64.obj loadconfig-min.obj 2>&1 | FileCheck --check-prefix=WARN %s +WARN: lld-link: warning: '__chpe_metadata' is missing for ARM64X target + #--- arm64-dllmain.s .section .text,"xr",discard,_DllMainCRTStartup .globl _DllMainCRTStartup @@ -87,6 +105,56 @@ func: mov w0, #2 ret +#--- amd64-dllmain.s + .section .text,"xr",discard,_DllMainCRTStartup + .globl _DllMainCRTStartup + .p2align 2 +_DllMainCRTStartup: + movl $3, %eax + retq + #--- arm64-drectve.s .section .drectve .ascii "-entry:func" + +#--- loadconfig-min.s + .section .rdata,"dr" + .globl _load_config_used + .p2align 3, 0 +_load_config_used: + .word 0x140 + .fill 0xc4,1,0 + .xword chpe_metadata + .fill 0x70,1,0 + + .p2align 3, 0 +chpe_metadata: + .word 2 + .rva __hybrid_code_map + .word __hybrid_code_map_count + .rva __x64_code_ranges_to_entry_points + .rva __arm64x_redirection_metadata + .word 0 // __os_arm64x_dispatch_call_no_redirect + .word 0 // __os_arm64x_dispatch_ret + .word 0 // __os_arm64x_check_call + .word 0 // __os_arm64x_check_icall + .word 0 // __os_arm64x_check_icall_cfg + .rva __arm64x_native_entrypoint + .rva __hybrid_auxiliary_iat + .word __x64_code_ranges_to_entry_points_count + .word __arm64x_redirection_metadata_count + .word 0 // __os_arm64x_get_x64_information + .word 0 // __os_arm64x_set_x64_information + .rva __arm64x_extra_rfe_table + .word __arm64x_extra_rfe_table_size + .word 0 // __os_arm64x_dispatch_fptr + .rva __hybrid_auxiliary_iat_copy + .rva __hybrid_auxiliary_delayload_iat + .rva __hybrid_auxiliary_delayload_iat_copy + .word __hybrid_image_info_bitfield + .word 0 // __os_arm64x_helper3 + .word 0 // __os_arm64x_helper4 + .word 0 // __os_arm64x_helper5 + .word 0 // __os_arm64x_helper6 + .word 0 // __os_arm64x_helper7 + .word 0 // __os_arm64x_helper8 diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 0c2c1a87a77d8..f92d7ee01fb91 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1224,9 +1224,9 @@ function(add_llvm_pass_plugin name) endif() set_property(GLOBAL APPEND PROPERTY LLVM_STATIC_EXTENSIONS ${name}) elseif(NOT ARG_NO_MODULE) - add_llvm_library(${name} MODULE ${ARG_UNPARSED_ARGUMENTS}) + add_llvm_library(${name} MODULE NO_EXPORT ${ARG_UNPARSED_ARGUMENTS}) else() - add_llvm_library(${name} OBJECT ${ARG_UNPARSED_ARGUMENTS}) + add_llvm_library(${name} OBJECT NO_EXPORT ${ARG_UNPARSED_ARGUMENTS}) endif() message(STATUS "Registering ${name} as a pass plugin (static build: ${LLVM_${name_upper}_LINK_INTO_TOOLS})") diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index 604dc9419025b..fd8784a4c1003 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -1480,6 +1480,10 @@ enum NodeType { // Output: Output Chain EXPERIMENTAL_VECTOR_HISTOGRAM, + // Finds the index of the last active mask element + // Operands: Mask + VECTOR_FIND_LAST_ACTIVE, + // llvm.clear_cache intrinsic // Operands: Input Chain, Start Addres, End Address // Outputs: Output Chain diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index ce58777655e06..38ac90f0c081b 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -4781,7 +4781,7 @@ class TargetLowering : public TargetLoweringBase { virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/, MachineFunction &/*MF*/, bool /*isVarArg*/, const SmallVectorImpl &/*Outs*/, - LLVMContext &/*Context*/) const + LLVMContext &/*Context*/, const Type *RetTy) const { // Return true by default to get preexisting behavior. return true; @@ -5368,6 +5368,11 @@ class TargetLowering : public TargetLoweringBase { /// \returns The expansion result or SDValue() if it fails. SDValue expandVPCTTZElements(SDNode *N, SelectionDAG &DAG) const; + /// Expand VECTOR_FIND_LAST_ACTIVE nodes + /// \param N Node to expand + /// \returns The expansion result or SDValue() if it fails. + SDValue expandVectorFindLastActive(SDNode *N, SelectionDAG &DAG) const; + /// Expand ABS nodes. Expands vector/scalar ABS nodes, /// vector nodes can only succeed if all operations are legal/custom. /// (ABS x) -> (XOR (ADD x, (SRA x, type_size)), (SRA x, type_size)) diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index be6166f0c4169..fa0079bac435c 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -2975,7 +2975,7 @@ bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) { return tokError("pointers to void are invalid - use i8* instead"); if (!PointerType::isValidElementType(Result)) return tokError("pointer to this type is invalid"); - Result = PointerType::getUnqual(Result); + Result = PointerType::getUnqual(Context); Lex.Lex(); break; @@ -2992,7 +2992,7 @@ bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) { parseToken(lltok::star, "expected '*' in address space")) return true; - Result = PointerType::get(Result, AddrSpace); + Result = PointerType::get(Context, AddrSpace); break; } @@ -6515,7 +6515,7 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine, return error(RetTypeLoc, "functions with 'sret' argument must return void"); FunctionType *FT = FunctionType::get(RetType, ParamTypeList, IsVarArg); - PointerType *PFT = PointerType::get(FT, AddrSpace); + PointerType *PFT = PointerType::get(Context, AddrSpace); Fn = nullptr; GlobalValue *FwdFn = nullptr; @@ -7410,7 +7410,7 @@ bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) { // Look up the callee. Value *Callee; - if (convertValIDToValue(PointerType::get(Ty, InvokeAddrSpace), CalleeID, + if (convertValIDToValue(PointerType::get(Context, InvokeAddrSpace), CalleeID, Callee, &PFS)) return true; @@ -7724,7 +7724,8 @@ bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) { // Look up the callee. Value *Callee; - if (convertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS)) + if (convertValIDToValue(PointerType::getUnqual(Context), CalleeID, Callee, + &PFS)) return true; // Set up the Attribute for the function. @@ -8115,8 +8116,8 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS, // Look up the callee. Value *Callee; - if (convertValIDToValue(PointerType::get(Ty, CallAddrSpace), CalleeID, Callee, - &PFS)) + if (convertValIDToValue(PointerType::get(Context, CallAddrSpace), CalleeID, + Callee, &PFS)) return true; // Set up the Attribute for the function. diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp index 8efe540770913..925d9af7d0e06 100644 --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -82,6 +82,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeMachineCycleInfoWrapperPassPass(Registry); initializeMachineDominatorTreeWrapperPassPass(Registry); initializeMachineFunctionPrinterPassPass(Registry); + initializeMachineFunctionSplitterPass(Registry); initializeMachineLateInstrsCleanupPass(Registry); initializeMachineLICMPass(Registry); initializeMachineLoopInfoWrapperPassPass(Registry); diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index ec5b058da2971..5a314570c776a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1001,7 +1001,7 @@ bool FastISel::lowerCallTo(CallLoweringInfo &CLI) { GetReturnInfo(CLI.CallConv, CLI.RetTy, getReturnAttrs(CLI), Outs, TLI, DL); bool CanLowerReturn = TLI.CanLowerReturn( - CLI.CallConv, *FuncInfo.MF, CLI.IsVarArg, Outs, CLI.RetTy->getContext()); + CLI.CallConv, *FuncInfo.MF, CLI.IsVarArg, Outs, CLI.RetTy->getContext(), CLI.RetTy); // FIXME: sret demotion isn't supported yet - bail out. if (!CanLowerReturn) diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index 1de336429fe10..3e89b18585f15 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -99,7 +99,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf, GetReturnInfo(CC, Fn->getReturnType(), Fn->getAttributes(), Outs, *TLI, mf.getDataLayout()); CanLowerReturn = - TLI->CanLowerReturn(CC, *MF, Fn->isVarArg(), Outs, Fn->getContext()); + TLI->CanLowerReturn(CC, *MF, Fn->isVarArg(), Outs, Fn->getContext(), Fn->getReturnType()); // If this personality uses funclets, we need to do a bit more work. DenseMap> CatchObjects; diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 7f7a9990476b5..b0a624680231e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -155,6 +155,10 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { case ISD::ZERO_EXTEND_VECTOR_INREG: Res = PromoteIntRes_EXTEND_VECTOR_INREG(N); break; + case ISD::VECTOR_FIND_LAST_ACTIVE: + Res = PromoteIntRes_VECTOR_FIND_LAST_ACTIVE(N); + break; + case ISD::SIGN_EXTEND: case ISD::VP_SIGN_EXTEND: case ISD::ZERO_EXTEND: @@ -2069,6 +2073,9 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM: Res = PromoteIntOp_VECTOR_HISTOGRAM(N, OpNo); break; + case ISD::VECTOR_FIND_LAST_ACTIVE: + Res = PromoteIntOp_VECTOR_FIND_LAST_ACTIVE(N, OpNo); + break; } // If the result is null, the sub-method took care of registering results etc. @@ -2810,6 +2817,13 @@ SDValue DAGTypeLegalizer::PromoteIntOp_VECTOR_HISTOGRAM(SDNode *N, return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0); } +SDValue DAGTypeLegalizer::PromoteIntOp_VECTOR_FIND_LAST_ACTIVE(SDNode *N, + unsigned OpNo) { + SmallVector NewOps(N->ops()); + NewOps[OpNo] = GetPromotedInteger(N->getOperand(OpNo)); + return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0); +} + //===----------------------------------------------------------------------===// // Integer Result Expansion //===----------------------------------------------------------------------===// @@ -6120,6 +6134,12 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTEND_VECTOR_INREG(SDNode *N) { return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0)); } +SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_FIND_LAST_ACTIVE(SDNode *N) { + EVT VT = N->getValueType(0); + EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); + return DAG.getNode(ISD::VECTOR_FIND_LAST_ACTIVE, SDLoc(N), NVT, N->ops()); +} + SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) { EVT OutVT = N->getValueType(0); EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index caaa40a64c7e1..f13f70e66cfaa 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -378,6 +378,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue PromoteIntRes_VPFunnelShift(SDNode *N); SDValue PromoteIntRes_IS_FPCLASS(SDNode *N); SDValue PromoteIntRes_PATCHPOINT(SDNode *N); + SDValue PromoteIntRes_VECTOR_FIND_LAST_ACTIVE(SDNode *N); // Integer Operand Promotion. bool PromoteIntegerOperand(SDNode *N, unsigned OpNo); @@ -428,6 +429,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue PromoteIntOp_VP_STRIDED(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_VP_SPLICE(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_VECTOR_HISTOGRAM(SDNode *N, unsigned OpNo); + SDValue PromoteIntOp_VECTOR_FIND_LAST_ACTIVE(SDNode *N, unsigned OpNo); void SExtOrZExtPromotedOperands(SDValue &LHS, SDValue &RHS); void PromoteSetCCOperands(SDValue &LHS,SDValue &RHS, ISD::CondCode Code); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index a6d1b1cb7b104..6ad08bce44b0a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -503,6 +503,7 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { case ISD::VECREDUCE_FMIN: case ISD::VECREDUCE_FMAXIMUM: case ISD::VECREDUCE_FMINIMUM: + case ISD::VECTOR_FIND_LAST_ACTIVE: Action = TLI.getOperationAction(Node->getOpcode(), Node->getOperand(0).getValueType()); break; @@ -1225,6 +1226,9 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl &Results) { case ISD::VECTOR_COMPRESS: Results.push_back(TLI.expandVECTOR_COMPRESS(Node, DAG)); return; + case ISD::VECTOR_FIND_LAST_ACTIVE: + Results.push_back(TLI.expandVectorFindLastActive(Node, DAG)); + return; case ISD::SCMP: case ISD::UCMP: Results.push_back(TLI.expandCMP(Node, DAG)); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 72557937a99bc..8a5d7c0b022d9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6427,42 +6427,25 @@ void SelectionDAGBuilder::visitVectorExtractLastActive(const CallInst &I, assert(Intrinsic == Intrinsic::experimental_vector_extract_last_active && "Tried lowering invalid vector extract last"); SDLoc sdl = getCurSDLoc(); + const DataLayout &Layout = DAG.getDataLayout(); SDValue Data = getValue(I.getOperand(0)); SDValue Mask = getValue(I.getOperand(1)); - SDValue PassThru = getValue(I.getOperand(2)); - EVT DataVT = Data.getValueType(); - EVT ScalarVT = PassThru.getValueType(); - EVT BoolVT = Mask.getValueType().getScalarType(); - - // Find a suitable type for a stepvector. - ConstantRange VScaleRange(1, /*isFullSet=*/true); // Dummy value. - if (DataVT.isScalableVector()) - VScaleRange = getVScaleRange(I.getCaller(), 64); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - unsigned EltWidth = TLI.getBitWidthForCttzElements( - I.getType(), DataVT.getVectorElementCount(), /*ZeroIsPoison=*/true, - &VScaleRange); - MVT StepVT = MVT::getIntegerVT(EltWidth); - EVT StepVecVT = DataVT.changeVectorElementType(StepVT); - - // Zero out lanes with inactive elements, then find the highest remaining - // value from the stepvector. - SDValue Zeroes = DAG.getConstant(0, sdl, StepVecVT); - SDValue StepVec = DAG.getStepVector(sdl, StepVecVT); - SDValue ActiveElts = DAG.getSelect(sdl, StepVecVT, Mask, StepVec, Zeroes); - SDValue HighestIdx = - DAG.getNode(ISD::VECREDUCE_UMAX, sdl, StepVT, ActiveElts); - - // Extract the corresponding lane from the data vector - EVT ExtVT = TLI.getVectorIdxTy(DAG.getDataLayout()); - SDValue Idx = DAG.getZExtOrTrunc(HighestIdx, sdl, ExtVT); - SDValue Extract = - DAG.getNode(ISD::EXTRACT_VECTOR_ELT, sdl, ScalarVT, Data, Idx); - - // If all mask lanes were inactive, choose the passthru value instead. - SDValue AnyActive = DAG.getNode(ISD::VECREDUCE_OR, sdl, BoolVT, Mask); - SDValue Result = DAG.getSelect(sdl, ScalarVT, AnyActive, Extract, PassThru); + EVT ResVT = TLI.getValueType(Layout, I.getType()); + + EVT ExtVT = TLI.getVectorIdxTy(Layout); + SDValue Idx = DAG.getNode(ISD::VECTOR_FIND_LAST_ACTIVE, sdl, ExtVT, Mask); + SDValue Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, sdl, ResVT, Data, Idx); + + Value *Default = I.getOperand(2); + if (!isa(Default) && !isa(Default)) { + SDValue PassThru = getValue(Default); + EVT BoolVT = Mask.getValueType().getScalarType(); + SDValue AnyActive = DAG.getNode(ISD::VECREDUCE_OR, sdl, BoolVT, Mask); + Result = DAG.getSelect(sdl, ResVT, AnyActive, Result, PassThru); + } + setValue(&I, Result); } @@ -11008,7 +10991,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const { bool CanLowerReturn = this->CanLowerReturn(CLI.CallConv, CLI.DAG.getMachineFunction(), - CLI.IsVarArg, Outs, CLI.RetTy->getContext()); + CLI.IsVarArg, Outs, CLI.RetTy->getContext(), CLI.RetTy); SDValue DemoteStackSlot; int DemoteStackIdx = -100; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp index 580ff19065557..f63c8dd3df1c8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -567,6 +567,9 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM: return "histogram"; + case ISD::VECTOR_FIND_LAST_ACTIVE: + return "find_last_active"; + // Vector Predication #define BEGIN_REGISTER_VP_SDNODE(SDID, LEGALARG, NAME, ...) \ case ISD::SDID: \ diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 56194e2614af2..368800d8b46a8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -12,6 +12,7 @@ #include "llvm/CodeGen/TargetLowering.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/CodeGenCommonISel.h" @@ -9451,6 +9452,43 @@ SDValue TargetLowering::expandVPCTTZElements(SDNode *N, return DAG.getNode(ISD::VP_REDUCE_UMIN, DL, ResVT, ExtEVL, Select, Mask, EVL); } +SDValue TargetLowering::expandVectorFindLastActive(SDNode *N, + SelectionDAG &DAG) const { + SDLoc DL(N); + SDValue Mask = N->getOperand(0); + EVT MaskVT = Mask.getValueType(); + EVT BoolVT = MaskVT.getScalarType(); + + // Find a suitable type for a stepvector. + ConstantRange VScaleRange(1, /*isFullSet=*/true); // Fixed length default. + if (MaskVT.isScalableVector()) + VScaleRange = getVScaleRange(&DAG.getMachineFunction().getFunction(), 64); + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + unsigned EltWidth = TLI.getBitWidthForCttzElements( + BoolVT.getTypeForEVT(*DAG.getContext()), MaskVT.getVectorElementCount(), + /*ZeroIsPoison=*/true, &VScaleRange); + EVT StepVT = MVT::getIntegerVT(EltWidth); + EVT StepVecVT = MaskVT.changeVectorElementType(StepVT); + + // If promotion is required to make the type legal, do it here; promotion + // of integers within LegalizeVectorOps is looking for types of the same + // size but with a smaller number of larger elements, not the usual larger + // size with the same number of larger elements. + if (TLI.getTypeAction(StepVecVT.getSimpleVT()) == + TargetLowering::TypePromoteInteger) { + StepVecVT = TLI.getTypeToTransformTo(*DAG.getContext(), StepVecVT); + StepVT = StepVecVT.getVectorElementType(); + } + + // Zero out lanes with inactive elements, then find the highest remaining + // value from the stepvector. + SDValue Zeroes = DAG.getConstant(0, DL, StepVecVT); + SDValue StepVec = DAG.getStepVector(DL, StepVecVT); + SDValue ActiveElts = DAG.getSelect(DL, StepVecVT, Mask, StepVec, Zeroes); + SDValue HighestIdx = DAG.getNode(ISD::VECREDUCE_UMAX, DL, StepVT, ActiveElts); + return DAG.getZExtOrTrunc(HighestIdx, DL, N->getValueType(0)); +} + SDValue TargetLowering::expandABS(SDNode *N, SelectionDAG &DAG, bool IsNegative) const { SDLoc dl(N); diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 3b0e9c7526fd0..73af0a9a71407 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -818,6 +818,9 @@ void TargetLoweringBase::initActions() { setOperationAction(ISD::SDOPC, VT, Expand); #include "llvm/IR/VPIntrinsics.def" + // Masked vector extracts default to expand. + setOperationAction(ISD::VECTOR_FIND_LAST_ACTIVE, VT, Expand); + // FP environment operations default to expand. setOperationAction(ISD::GET_FPENV, VT, Expand); setOperationAction(ISD::SET_FPENV, VT, Expand); diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 06e62bf7f9f75..a1bae1b50764d 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -1875,9 +1875,6 @@ static Value *upgradeX86ConcatShift(IRBuilder<> &Builder, CallBase &CI, static Value *upgradeMaskedStore(IRBuilder<> &Builder, Value *Ptr, Value *Data, Value *Mask, bool Aligned) { - // Cast the pointer to the right type. - Ptr = Builder.CreateBitCast(Ptr, - llvm::PointerType::getUnqual(Data->getType())); const Align Alignment = Aligned ? Align(Data->getType()->getPrimitiveSizeInBits().getFixedValue() / 8) @@ -1897,8 +1894,6 @@ static Value *upgradeMaskedStore(IRBuilder<> &Builder, Value *Ptr, Value *Data, static Value *upgradeMaskedLoad(IRBuilder<> &Builder, Value *Ptr, Value *Passthru, Value *Mask, bool Aligned) { Type *ValTy = Passthru->getType(); - // Cast the pointer to the right type. - Ptr = Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(ValTy)); const Align Alignment = Aligned ? Align( @@ -2421,13 +2416,10 @@ static Value *upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, // Nontemporal (unaligned) store of the 0'th element of the float/double // vector. - Type *SrcEltTy = cast(Arg1->getType())->getElementType(); - PointerType *EltPtrTy = PointerType::getUnqual(SrcEltTy); - Value *Addr = Builder.CreateBitCast(Arg0, EltPtrTy, "cast"); Value *Extract = Builder.CreateExtractElement(Arg1, (uint64_t)0, "extractelement"); - StoreInst *SI = Builder.CreateAlignedStore(Extract, Addr, Align(1)); + StoreInst *SI = Builder.CreateAlignedStore(Extract, Arg0, Align(1)); SI->setMetadata(LLVMContext::MD_nontemporal, Node); } else if (Name.starts_with("avx.movnt.") || Name.starts_with("avx512.storent.")) { @@ -2439,11 +2431,8 @@ static Value *upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, Value *Arg0 = CI->getArgOperand(0); Value *Arg1 = CI->getArgOperand(1); - // Convert the type of the pointer to a pointer to the stored type. - Value *BC = Builder.CreateBitCast( - Arg0, PointerType::getUnqual(Arg1->getType()), "cast"); StoreInst *SI = Builder.CreateAlignedStore( - Arg1, BC, + Arg1, Arg0, Align(Arg1->getType()->getPrimitiveSizeInBits().getFixedValue() / 8)); SI->setMetadata(LLVMContext::MD_nontemporal, Node); } else if (Name == "sse2.storel.dq") { @@ -2453,17 +2442,12 @@ static Value *upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, auto *NewVecTy = FixedVectorType::get(Type::getInt64Ty(C), 2); Value *BC0 = Builder.CreateBitCast(Arg1, NewVecTy, "cast"); Value *Elt = Builder.CreateExtractElement(BC0, (uint64_t)0); - Value *BC = Builder.CreateBitCast( - Arg0, PointerType::getUnqual(Elt->getType()), "cast"); - Builder.CreateAlignedStore(Elt, BC, Align(1)); + Builder.CreateAlignedStore(Elt, Arg0, Align(1)); } else if (Name.starts_with("sse.storeu.") || Name.starts_with("sse2.storeu.") || Name.starts_with("avx.storeu.")) { Value *Arg0 = CI->getArgOperand(0); Value *Arg1 = CI->getArgOperand(1); - - Arg0 = Builder.CreateBitCast(Arg0, PointerType::getUnqual(Arg1->getType()), - "cast"); Builder.CreateAlignedStore(Arg1, Arg0, Align(1)); } else if (Name == "avx512.mask.store.ss") { Value *Mask = Builder.CreateAnd(CI->getArgOperand(2), Builder.getInt8(1)); @@ -2813,31 +2797,21 @@ static Value *upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, CI->getArgOperand(2), Aligned); } else if (Name.starts_with("avx512.mask.expand.load.")) { auto *ResultTy = cast(CI->getType()); - Type *PtrTy = ResultTy->getElementType(); - - // Cast the pointer to element type. - Value *Ptr = Builder.CreateBitCast(CI->getOperand(0), - llvm::PointerType::getUnqual(PtrTy)); - Value *MaskVec = getX86MaskVec(Builder, CI->getArgOperand(2), ResultTy->getNumElements()); - Rep = Builder.CreateIntrinsic(Intrinsic::masked_expandload, ResultTy, - {Ptr, MaskVec, CI->getOperand(1)}); + Rep = Builder.CreateIntrinsic( + Intrinsic::masked_expandload, ResultTy, + {CI->getOperand(0), MaskVec, CI->getOperand(1)}); } else if (Name.starts_with("avx512.mask.compress.store.")) { auto *ResultTy = cast(CI->getArgOperand(1)->getType()); - Type *PtrTy = ResultTy->getElementType(); - - // Cast the pointer to element type. - Value *Ptr = Builder.CreateBitCast(CI->getOperand(0), - llvm::PointerType::getUnqual(PtrTy)); - Value *MaskVec = getX86MaskVec(Builder, CI->getArgOperand(2), cast(ResultTy)->getNumElements()); - Rep = Builder.CreateIntrinsic(Intrinsic::masked_compressstore, ResultTy, - {CI->getArgOperand(1), Ptr, MaskVec}); + Rep = Builder.CreateIntrinsic( + Intrinsic::masked_compressstore, ResultTy, + {CI->getArgOperand(1), CI->getArgOperand(0), MaskVec}); } else if (Name.starts_with("avx512.mask.compress.") || Name.starts_with("avx512.mask.expand.")) { auto *ResultTy = cast(CI->getType()); @@ -2963,9 +2937,7 @@ static Value *upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, Type *EltTy = cast(CI->getType())->getElementType(); unsigned NumSrcElts = 128 / EltTy->getPrimitiveSizeInBits(); auto *VT = FixedVectorType::get(EltTy, NumSrcElts); - Value *Op = Builder.CreatePointerCast(CI->getArgOperand(0), - PointerType::getUnqual(VT)); - Value *Load = Builder.CreateAlignedLoad(VT, Op, Align(1)); + Value *Load = Builder.CreateAlignedLoad(VT, CI->getArgOperand(0), Align(1)); if (NumSrcElts == 2) Rep = Builder.CreateShuffleVector(Load, ArrayRef{0, 1, 0, 1}); else @@ -3687,13 +3659,8 @@ static Value *upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, MDNode *Node = MDNode::get( C, ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(C), 1))); - Value *Ptr = CI->getArgOperand(0); - - // Convert the type of the pointer to a pointer to the stored type. - Value *BC = Builder.CreateBitCast( - Ptr, PointerType::getUnqual(CI->getType()), "cast"); LoadInst *LI = Builder.CreateAlignedLoad( - CI->getType(), BC, + CI->getType(), CI->getArgOperand(0), Align(CI->getType()->getPrimitiveSizeInBits().getFixedValue() / 8)); LI->setMetadata(LLVMContext::MD_nontemporal, Node); Rep = LI; @@ -4045,10 +4012,7 @@ static Value *upgradeX86IntrinsicCall(StringRef Name, CallBase *CI, Function *F, // Extract the second result and store it. Value *Data = Builder.CreateExtractValue(NewCall, 1); - // Cast the pointer to the right type. - Value *Ptr = Builder.CreateBitCast( - CI->getArgOperand(3), llvm::PointerType::getUnqual(Data->getType())); - Builder.CreateAlignedStore(Data, Ptr, Align(1)); + Builder.CreateAlignedStore(Data, CI->getArgOperand(3), Align(1)); // Replace the original call result with the first result of the new call. Value *CF = Builder.CreateExtractValue(NewCall, 0); @@ -4756,10 +4720,7 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { NewCall = Builder.CreateCall(NewFn); // Extract the second result and store it. Value *Data = Builder.CreateExtractValue(NewCall, 1); - // Cast the pointer to the right type. - Value *Ptr = Builder.CreateBitCast(CI->getArgOperand(0), - llvm::PointerType::getUnqual(Data->getType())); - Builder.CreateAlignedStore(Data, Ptr, Align(1)); + Builder.CreateAlignedStore(Data, CI->getArgOperand(0), Align(1)); // Replace the original call result with the first result of the new call. Value *TSC = Builder.CreateExtractValue(NewCall, 0); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index e4715018d84ca..8a3a9f75415fb 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -9702,7 +9702,8 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, bool AArch64TargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { CCAssignFn *RetCC = CCAssignFnForReturn(CallConv); SmallVector RVLocs; CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h index 85b62be5dd30d..61579de50db17 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -1103,7 +1103,7 @@ class AArch64TargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp index 7f10bfed739b4..050fd71d3b143 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -3623,7 +3623,13 @@ InstructionCost AArch64TTIImpl::getArithmeticInstrCost( // so the cost can be cheaper (smull or umull). if (LT.second != MVT::v2i64 || isWideningInstruction(Ty, Opcode, Args)) return LT.first; - return LT.first * 14; + return cast(Ty)->getElementCount().getKnownMinValue() * + (getArithmeticInstrCost(Opcode, Ty->getScalarType(), CostKind) + + getVectorInstrCost(Instruction::ExtractElement, Ty, CostKind, -1, + nullptr, nullptr) * + 2 + + getVectorInstrCost(Instruction::InsertElement, Ty, CostKind, -1, + nullptr, nullptr)); case ISD::ADD: case ISD::XOR: case ISD::OR: diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h index 89356df39724a..5d9a830f041a7 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPU.h +++ b/llvm/lib/Target/AMDGPU/AMDGPU.h @@ -216,8 +216,8 @@ extern char &SIPreEmitPeepholeID; void initializeSILateBranchLoweringPass(PassRegistry &); extern char &SILateBranchLoweringPassID; -void initializeSIOptimizeExecMaskingPass(PassRegistry &); -extern char &SIOptimizeExecMaskingID; +void initializeSIOptimizeExecMaskingLegacyPass(PassRegistry &); +extern char &SIOptimizeExecMaskingLegacyID; void initializeSIPreAllocateWWMRegsLegacyPass(PassRegistry &); extern char &SIPreAllocateWWMRegsLegacyID; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def index fbcf83e2fdd60..09a39d23d801b 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def +++ b/llvm/lib/Target/AMDGPU/AMDGPUPassRegistry.def @@ -105,6 +105,7 @@ MACHINE_FUNCTION_PASS("si-load-store-opt", SILoadStoreOptimizerPass()) MACHINE_FUNCTION_PASS("si-lower-control-flow", SILowerControlFlowPass()) MACHINE_FUNCTION_PASS("si-lower-sgpr-spills", SILowerSGPRSpillsPass()) MACHINE_FUNCTION_PASS("si-opt-vgpr-liverange", SIOptimizeVGPRLiveRangePass()) +MACHINE_FUNCTION_PASS("si-optimize-exec-masking", SIOptimizeExecMaskingPass()) MACHINE_FUNCTION_PASS("si-peephole-sdwa", SIPeepholeSDWAPass()) MACHINE_FUNCTION_PASS("si-pre-allocate-wwm-regs", SIPreAllocateWWMRegsPass()) MACHINE_FUNCTION_PASS("si-shrink-instructions", SIShrinkInstructionsPass()) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index 98268b848f5ce..53ec80b8f7204 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -42,6 +42,7 @@ #include "SILowerSGPRSpills.h" #include "SIMachineFunctionInfo.h" #include "SIMachineScheduler.h" +#include "SIOptimizeExecMasking.h" #include "SIOptimizeVGPRLiveRange.h" #include "SIPeepholeSDWA.h" #include "SIPreAllocateWWMRegs.h" @@ -528,7 +529,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUTarget() { initializeSIPreEmitPeepholePass(*PR); initializeSILateBranchLoweringPass(*PR); initializeSIMemoryLegalizerPass(*PR); - initializeSIOptimizeExecMaskingPass(*PR); + initializeSIOptimizeExecMaskingLegacyPass(*PR); initializeSIPreAllocateWWMRegsLegacyPass(*PR); initializeSIFormMemoryClausesPass(*PR); initializeSIPostRABundlerPass(*PR); @@ -1634,7 +1635,7 @@ bool GCNPassConfig::addRegAssignAndRewriteOptimized() { void GCNPassConfig::addPostRegAlloc() { addPass(&SIFixVGPRCopiesID); if (getOptLevel() > CodeGenOptLevel::None) - addPass(&SIOptimizeExecMaskingID); + addPass(&SIOptimizeExecMaskingLegacyID); TargetPassConfig::addPostRegAlloc(); } @@ -2105,6 +2106,13 @@ void AMDGPUCodeGenPassBuilder::addMachineSSAOptimization( addPass(SIShrinkInstructionsPass()); } +void AMDGPUCodeGenPassBuilder::addPostRegAlloc(AddMachinePass &addPass) const { + // addPass(SIFixVGPRCopiesID); + if (TM.getOptLevel() > CodeGenOptLevel::None) + addPass(SIOptimizeExecMaskingPass()); + Base::addPostRegAlloc(addPass); +} + bool AMDGPUCodeGenPassBuilder::isPassEnabled(const cl::opt &Opt, CodeGenOptLevel Level) const { if (Opt.getNumOccurrences()) diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h index 5ba58a92621ed..24b4da3a68f67 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h @@ -176,6 +176,7 @@ class AMDGPUCodeGenPassBuilder void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const; Error addInstSelector(AddMachinePass &) const; void addMachineSSAOptimization(AddMachinePass &) const; + void addPostRegAlloc(AddMachinePass &) const; /// Check if a pass is enabled given \p Opt option. The option always /// overrides defaults if explicitly used. Otherwise its default will be used diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index e068b5f0b8769..c4b1038b12d04 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -3157,7 +3157,8 @@ SDValue SITargetLowering::LowerFormalArguments( // possible in registers before passing on stack. bool SITargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { // Replacing returns with sret/stack usage doesn't make sense for shaders. // FIXME: Also sort of a workaround for custom vector splitting in LowerReturn // for shaders. Vector types should be explicitly handled by CC. diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.h b/llvm/lib/Target/AMDGPU/SIISelLowering.h index bbb96d9115a0a..1cd7f1b29e077 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.h +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.h @@ -392,7 +392,7 @@ class SITargetLowering final : public AMDGPUTargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp b/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp index 93b70fa4ba974..3fb8d5b560496 100644 --- a/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp +++ b/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "SIOptimizeExecMasking.h" #include "AMDGPU.h" #include "GCNSubtarget.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" @@ -23,7 +24,7 @@ using namespace llvm; namespace { -class SIOptimizeExecMasking : public MachineFunctionPass { +class SIOptimizeExecMasking { MachineFunction *MF = nullptr; const GCNSubtarget *ST = nullptr; const SIRegisterInfo *TRI = nullptr; @@ -61,11 +62,16 @@ class SIOptimizeExecMasking : public MachineFunctionPass { void tryRecordOrSaveexecXorSequence(MachineInstr &MI); bool optimizeOrSaveexecXorSequences(); +public: + bool run(MachineFunction &MF); +}; + +class SIOptimizeExecMaskingLegacy : public MachineFunctionPass { public: static char ID; - SIOptimizeExecMasking() : MachineFunctionPass(ID) { - initializeSIOptimizeExecMaskingPass(*PassRegistry::getPassRegistry()); + SIOptimizeExecMaskingLegacy() : MachineFunctionPass(ID) { + initializeSIOptimizeExecMaskingLegacyPass(*PassRegistry::getPassRegistry()); } bool runOnMachineFunction(MachineFunction &MF) override; @@ -82,15 +88,28 @@ class SIOptimizeExecMasking : public MachineFunctionPass { } // End anonymous namespace. -INITIALIZE_PASS_BEGIN(SIOptimizeExecMasking, DEBUG_TYPE, +PreservedAnalyses +SIOptimizeExecMaskingPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &) { + SIOptimizeExecMasking Impl; + + if (!Impl.run(MF)) + return PreservedAnalyses::all(); + + auto PA = getMachineFunctionPassPreservedAnalyses(); + PA.preserveSet(); + return PA; +} + +INITIALIZE_PASS_BEGIN(SIOptimizeExecMaskingLegacy, DEBUG_TYPE, "SI optimize exec mask operations", false, false) INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass) -INITIALIZE_PASS_END(SIOptimizeExecMasking, DEBUG_TYPE, +INITIALIZE_PASS_END(SIOptimizeExecMaskingLegacy, DEBUG_TYPE, "SI optimize exec mask operations", false, false) -char SIOptimizeExecMasking::ID = 0; +char SIOptimizeExecMaskingLegacy::ID = 0; -char &llvm::SIOptimizeExecMaskingID = SIOptimizeExecMasking::ID; +char &llvm::SIOptimizeExecMaskingLegacyID = SIOptimizeExecMaskingLegacy::ID; /// If \p MI is a copy from exec, return the register copied to. Register SIOptimizeExecMasking::isCopyFromExec(const MachineInstr &MI) const { @@ -786,10 +805,14 @@ bool SIOptimizeExecMasking::optimizeOrSaveexecXorSequences() { return Changed; } -bool SIOptimizeExecMasking::runOnMachineFunction(MachineFunction &MF) { +bool SIOptimizeExecMaskingLegacy::runOnMachineFunction(MachineFunction &MF) { if (skipFunction(MF.getFunction())) return false; + return SIOptimizeExecMasking().run(MF); +} + +bool SIOptimizeExecMasking::run(MachineFunction &MF) { this->MF = &MF; ST = &MF.getSubtarget(); TRI = ST->getRegisterInfo(); diff --git a/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.h b/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.h new file mode 100644 index 0000000000000..f170a4733279b --- /dev/null +++ b/llvm/lib/Target/AMDGPU/SIOptimizeExecMasking.h @@ -0,0 +1,23 @@ +//===- SIOptimizeExecMasking.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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AMDGPU_SIOPTIMIZEEXECMASKING_H +#define LLVM_LIB_TARGET_AMDGPU_SIOPTIMIZEEXECMASKING_H + +#include "llvm/CodeGen/MachinePassManager.h" + +namespace llvm { +class SIOptimizeExecMaskingPass + : public PassInfoMixin { +public: + PreservedAnalyses run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM); +}; +} // namespace llvm + +#endif // LLVM_LIB_TARGET_AMDGPU_SIOPTIMIZEEXECMASKING_H diff --git a/llvm/lib/Target/ARC/ARCISelLowering.cpp b/llvm/lib/Target/ARC/ARCISelLowering.cpp index 5ab27681361db..b133e4e5299a5 100644 --- a/llvm/lib/Target/ARC/ARCISelLowering.cpp +++ b/llvm/lib/Target/ARC/ARCISelLowering.cpp @@ -630,7 +630,8 @@ SDValue ARCTargetLowering::LowerCallArguments( bool ARCTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); if (!CCInfo.CheckReturn(Outs, RetCC_ARC)) diff --git a/llvm/lib/Target/ARC/ARCISelLowering.h b/llvm/lib/Target/ARC/ARCISelLowering.h index e070ed8752cce..716a72455e827 100644 --- a/llvm/lib/Target/ARC/ARCISelLowering.h +++ b/llvm/lib/Target/ARC/ARCISelLowering.h @@ -112,7 +112,7 @@ class ARCTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &ArgsFlags, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; bool mayBeEmittedAsTailCall(const CallInst *CI) const override; }; diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 2e517c21fc4a8..bd8d6079e1ba8 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -3241,7 +3241,7 @@ bool ARMTargetLowering::CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const { + LLVMContext &Context, const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, isVarArg)); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h index 3c1a414af8597..9fad056edd3f1 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -965,7 +965,7 @@ class VectorType; bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp index 07c79f6f227b0..c73ff83d29789 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.cpp +++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp @@ -1670,7 +1670,8 @@ SDValue AVRTargetLowering::LowerCallResult( bool AVRTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { if (CallConv == CallingConv::AVR_BUILTIN) { SmallVector RVLocs; CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); diff --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h index f605795934532..cd45444e2bc3a 100644 --- a/llvm/lib/Target/AVR/AVRISelLowering.h +++ b/llvm/lib/Target/AVR/AVRISelLowering.h @@ -172,7 +172,7 @@ class AVRTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/CSKY/CSKYISelLowering.cpp b/llvm/lib/Target/CSKY/CSKYISelLowering.cpp index c3fc9f9ead5eb..4cea262d40a37 100644 --- a/llvm/lib/Target/CSKY/CSKYISelLowering.cpp +++ b/llvm/lib/Target/CSKY/CSKYISelLowering.cpp @@ -426,7 +426,8 @@ SDValue CSKYTargetLowering::LowerFormalArguments( bool CSKYTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { SmallVector CSKYLocs; CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context); return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg)); diff --git a/llvm/lib/Target/CSKY/CSKYISelLowering.h b/llvm/lib/Target/CSKY/CSKYISelLowering.h index d59481af3c5ba..0accfcad1879f 100644 --- a/llvm/lib/Target/CSKY/CSKYISelLowering.h +++ b/llvm/lib/Target/CSKY/CSKYISelLowering.h @@ -61,7 +61,7 @@ class CSKYTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index a19f9749cd9e3..12ca0c505bd06 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -182,7 +182,7 @@ bool HexagonTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const { + LLVMContext &Context, const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h index 3fd961f5a7462..aaa9c65c1e07e 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -249,7 +249,7 @@ class HexagonTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp index da55b7b8c6d68..e0792b36ce4d8 100644 --- a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp +++ b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp @@ -527,7 +527,8 @@ SDValue LanaiTargetLowering::LowerCCCArguments( bool LanaiTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.h b/llvm/lib/Target/Lanai/LanaiISelLowering.h index 5fa5444b51618..ebec2525b93cd 100644 --- a/llvm/lib/Target/Lanai/LanaiISelLowering.h +++ b/llvm/lib/Target/Lanai/LanaiISelLowering.h @@ -93,7 +93,7 @@ class LanaiTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override; diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 2417455808751..f9f1b097623e0 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -468,11 +468,10 @@ SDValue LoongArchTargetLowering::lowerBITREVERSE(SDValue Op, for (unsigned int i = 0; i < NewEltNum; i++) { SDValue Op = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i64, NewSrc, DAG.getConstant(i, DL, MVT::i64)); - SDValue RevOp = DAG.getNode((ResTy == MVT::v16i8 || ResTy == MVT::v32i8) - ? LoongArchISD::BITREV_8B - : ISD::BITREVERSE, - DL, MVT::i64, Op); - Ops.push_back(RevOp); + unsigned RevOp = (ResTy == MVT::v16i8 || ResTy == MVT::v32i8) + ? (unsigned)LoongArchISD::BITREV_8B + : (unsigned)ISD::BITREVERSE; + Ops.push_back(DAG.getNode(RevOp, DL, MVT::i64, Op)); } SDValue Res = DAG.getNode(ISD::BITCAST, DL, ResTy, DAG.getBuildVector(NewVT, DL, Ops)); @@ -5678,7 +5677,8 @@ LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI, bool LoongArchTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h index e619cb69f3332..e1bab9ebdd3f0 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h @@ -183,7 +183,7 @@ class LoongArchTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, const SDLoc &DL, diff --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp index 4297325cf0e64..39b307b28889c 100644 --- a/llvm/lib/Target/M68k/M68kISelLowering.cpp +++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp @@ -1060,7 +1060,8 @@ SDValue M68kTargetLowering::LowerFormalArguments( bool M68kTargetLowering::CanLowerReturn( CallingConv::ID CCID, MachineFunction &MF, bool IsVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CCID, IsVarArg, MF, RVLocs, Context); return CCInfo.CheckReturn(Outs, RetCC_M68k); diff --git a/llvm/lib/Target/M68k/M68kISelLowering.h b/llvm/lib/Target/M68k/M68kISelLowering.h index d00907775f928..e01f333316db6 100644 --- a/llvm/lib/Target/M68k/M68kISelLowering.h +++ b/llvm/lib/Target/M68k/M68kISelLowering.h @@ -271,7 +271,7 @@ class M68kTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; /// Lower the result values of a call into the /// appropriate copies out of appropriate physical registers. diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp index 31b793e9c0f2f..28d782543b330 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -723,7 +723,8 @@ MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const { + LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); return CCInfo.CheckReturn(Outs, RetCC_MSP430); diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.h b/llvm/lib/Target/MSP430/MSP430ISelLowering.h index 667ad60338619..d1263e453dda1 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.h +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.h @@ -171,7 +171,7 @@ namespace llvm { MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/Mips/MipsCCState.cpp b/llvm/lib/Target/Mips/MipsCCState.cpp index 76acfa97c3b41..781bb7c8c7e6d 100644 --- a/llvm/lib/Target/Mips/MipsCCState.cpp +++ b/llvm/lib/Target/Mips/MipsCCState.cpp @@ -95,14 +95,13 @@ void MipsCCState::PreAnalyzeCallResultForF128( /// Identify lowered values that originated from f128 or float arguments and /// record this for use by RetCC_MipsN. -void MipsCCState::PreAnalyzeReturnForF128( - const SmallVectorImpl &Outs) { - const MachineFunction &MF = getMachineFunction(); +void MipsCCState::PreAnalyzeCallReturnForF128( + const SmallVectorImpl &Outs, const Type *RetTy) { for (unsigned i = 0; i < Outs.size(); ++i) { OriginalArgWasF128.push_back( - originalTypeIsF128(MF.getFunction().getReturnType(), nullptr)); + originalTypeIsF128(RetTy, nullptr)); OriginalArgWasFloat.push_back( - MF.getFunction().getReturnType()->isFloatingPointTy()); + RetTy->isFloatingPointTy()); } } diff --git a/llvm/lib/Target/Mips/MipsCCState.h b/llvm/lib/Target/Mips/MipsCCState.h index bbb5225d5f678..4229da564630d 100644 --- a/llvm/lib/Target/Mips/MipsCCState.h +++ b/llvm/lib/Target/Mips/MipsCCState.h @@ -49,7 +49,7 @@ class MipsCCState : public CCState { /// Identify lowered values that originated from f128 arguments and record /// this for use by RetCC_MipsN. - void PreAnalyzeReturnForF128(const SmallVectorImpl &Outs); + void PreAnalyzeCallReturnForF128(const SmallVectorImpl &Outs, const Type *RetTy); /// Identify lowered values that originated from f128 arguments and record /// this. @@ -167,10 +167,11 @@ class MipsCCState : public CCState { void PreAnalyzeReturn(const SmallVectorImpl &Outs, CCAssignFn Fn) { + const MachineFunction &MF = getMachineFunction(); OriginalArgWasFloat.clear(); OriginalArgWasF128.clear(); OriginalArgWasFloatVector.clear(); - PreAnalyzeReturnForF128(Outs); + PreAnalyzeCallReturnForF128(Outs, MF.getFunction().getReturnType()); PreAnalyzeReturnForVectorFloat(Outs); } @@ -182,7 +183,8 @@ class MipsCCState : public CCState { bool CheckReturn(const SmallVectorImpl &ArgsFlags, CCAssignFn Fn) { - PreAnalyzeReturnForF128(ArgsFlags); + const MachineFunction &MF = getMachineFunction(); + PreAnalyzeCallReturnForF128(ArgsFlags, MF.getFunction().getReturnType()); PreAnalyzeReturnForVectorFloat(ArgsFlags); bool Return = CCState::CheckReturn(ArgsFlags, Fn); OriginalArgWasFloat.clear(); @@ -191,6 +193,16 @@ class MipsCCState : public CCState { return Return; } + bool CheckCallReturn(const SmallVectorImpl &ArgsFlags, + CCAssignFn Fn, const Type *RetTy) { + PreAnalyzeCallReturnForF128(ArgsFlags, RetTy); + PreAnalyzeReturnForVectorFloat(ArgsFlags); + bool Return = CCState::CheckReturn(ArgsFlags, Fn); + OriginalArgWasFloat.clear(); + OriginalArgWasF128.clear(); + OriginalArgWasFloatVector.clear(); + return Return; + } bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; } bool WasOriginalArgFloat(unsigned ValNo) { return OriginalArgWasFloat[ValNo]; diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index d5f38c414e703..30b2ea1f4798d 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -3864,10 +3864,10 @@ bool MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const { + LLVMContext &Context, const Type *RetTy) const { SmallVector RVLocs; MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); - return CCInfo.CheckReturn(Outs, RetCC_Mips); + return CCInfo.CheckCallReturn(Outs, RetCC_Mips, RetTy); } bool MipsTargetLowering::shouldSignExtendTypeInLibCall(Type *Ty, diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h index 655a347679ad7..ff4d089d6a49a 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.h +++ b/llvm/lib/Target/Mips/MipsISelLowering.h @@ -615,7 +615,7 @@ class TargetRegisterClass; bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 691107abf3e89..4ca328bd9a9ba 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -7868,7 +7868,8 @@ bool PPCTargetLowering::CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const { + LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); return CCInfo.CheckReturn( diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index 5d692e3fcae92..cc01cab7a2089 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -1373,7 +1373,7 @@ namespace llvm { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index f4f511a7368f8..d1a5a76029145 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -20609,7 +20609,8 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI, bool RISCVTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h index 892c1cd96ca61..21747cc353203 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -766,7 +766,7 @@ class RISCVTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, const SDLoc &DL, diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp index e236d646e66fc..784bbe8e662c2 100644 --- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp @@ -535,15 +535,15 @@ extern Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy, static SPIRV::MemorySemantics::MemorySemantics getSPIRVMemSemantics(std::memory_order MemOrder) { switch (MemOrder) { - case std::memory_order::memory_order_relaxed: + case std::memory_order_relaxed: return SPIRV::MemorySemantics::None; - case std::memory_order::memory_order_acquire: + case std::memory_order_acquire: return SPIRV::MemorySemantics::Acquire; - case std::memory_order::memory_order_release: + case std::memory_order_release: return SPIRV::MemorySemantics::Release; - case std::memory_order::memory_order_acq_rel: + case std::memory_order_acq_rel: return SPIRV::MemorySemantics::AcquireRelease; - case std::memory_order::memory_order_seq_cst: + case std::memory_order_seq_cst: return SPIRV::MemorySemantics::SequentiallyConsistent; default: report_fatal_error("Unknown CL memory scope"); diff --git a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp index ecf9b6ddae1fc..028699e56a946 100644 --- a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp @@ -22,6 +22,7 @@ #include "SPIRVSubtarget.h" #include "SPIRVTargetMachine.h" #include "SPIRVUtils.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/IR/IRBuilder.h" @@ -30,7 +31,6 @@ #include "llvm/IR/IntrinsicsSPIRV.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/LowerMemIntrinsics.h" -#include #include using namespace llvm; @@ -228,9 +228,7 @@ static SmallVector parseAnnotation(Value *I, } else { MDsItem.push_back(MDString::get(Ctx, Item)); } - } else if (int32_t Num; - std::from_chars(Item.data(), Item.data() + Item.size(), Num) - .ec == std::errc{}) { + } else if (int32_t Num; llvm::to_integer(StringRef(Item), Num, 10)) { MDsItem.push_back( ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Num))); } else { diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h index 60649eac62815..fd48098257065 100644 --- a/llvm/lib/Target/SPIRV/SPIRVUtils.h +++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h @@ -22,6 +22,7 @@ #include "llvm/IR/TypedPointerType.h" #include #include +#include #include namespace llvm { diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 03a74b6254300..d0cd38cf72363 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -234,7 +234,8 @@ static unsigned toCallerWindow(unsigned Reg) { bool SparcTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); return CCInfo.CheckReturn(Outs, Subtarget->is64Bit() ? RetCC_Sparc64 diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h index cc672074a4be8..1bee5f4cfe84d 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.h +++ b/llvm/lib/Target/Sparc/SparcISelLowering.h @@ -153,7 +153,7 @@ namespace llvm { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index d664b4a41fce7..e3dfab962f55f 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -2412,7 +2412,8 @@ bool SystemZTargetLowering:: CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const { + LLVMContext &Context, + const Type *RetTy) const { // Special case that we cannot easily detect in RetCC_SystemZ since // i128 may not be a legal type. for (auto &Out : Outs) diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h index d663e4abfb4e3..afd3d0d989a22 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h @@ -620,7 +620,8 @@ class SystemZTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, + const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, const SDLoc &DL, diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp index 87c1625c11454..aff058868f306 100644 --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -65,7 +65,8 @@ CCAssignFn *getParamCC(CallingConv::ID CallConv, bool IsVarArg) { bool VETargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { CCAssignFn *RetCC = getReturnCC(CallConv); SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); diff --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h index 8b9412d786625..04274b14baa1f 100644 --- a/llvm/lib/Target/VE/VEISelLowering.h +++ b/llvm/lib/Target/VE/VEISelLowering.h @@ -191,7 +191,8 @@ class VETargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &ArgsFlags, - LLVMContext &Context) const override; + LLVMContext &Context, + const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, const SDLoc &dl, diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 084aed6eed46d..02db1b142a22b 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -1429,7 +1429,8 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI, bool WebAssemblyTargetLowering::CanLowerReturn( CallingConv::ID /*CallConv*/, MachineFunction & /*MF*/, bool /*IsVarArg*/, const SmallVectorImpl &Outs, - LLVMContext & /*Context*/) const { + LLVMContext & /*Context*/, + const Type *RetTy) const { // WebAssembly can only handle returning tuples with multivalue enabled return WebAssembly::canLowerReturn(Outs.size(), Subtarget); } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h index 454432728ca87..d9ced1a1a5279 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h @@ -87,7 +87,8 @@ class WebAssemblyTargetLowering final : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, + const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, const SDLoc &dl, diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index eaedaa0b88d22..03f10a3c83e30 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1803,7 +1803,8 @@ namespace llvm { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, + const Type *RetTy) const override; const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override; ArrayRef getRoundingControlRegisters() const override; diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp index b1c1ab4aa855d..10aa2a5e5dac8 100644 --- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp +++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp @@ -659,7 +659,8 @@ X86TargetLowering::getSafeStackPointerLocation(IRBuilderBase &IRB) const { bool X86TargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); return CCInfo.CheckReturn(Outs, RetCC_X86); diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp index 9a9acaca3188e..ac199230b2c07 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp @@ -1325,7 +1325,7 @@ bool XCoreTargetLowering:: CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const { + LLVMContext &Context, const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); if (!CCInfo.CheckReturn(Outs, RetCC_XCore)) diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.h b/llvm/lib/Target/XCore/XCoreISelLowering.h index eaa36d40cba92..1e036ea316978 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.h +++ b/llvm/lib/Target/XCore/XCoreISelLowering.h @@ -217,7 +217,7 @@ namespace llvm { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &ArgsFlags, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; }; } diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index e8ede330bbac5..cdf38a0669479 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -621,7 +621,8 @@ XtensaTargetLowering::LowerCall(CallLoweringInfo &CLI, bool XtensaTargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, - const SmallVectorImpl &Outs, LLVMContext &Context) const { + const SmallVectorImpl &Outs, LLVMContext &Context, + const Type *RetTy) const { SmallVector RVLocs; CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); return CCInfo.CheckReturn(Outs, RetCC_Xtensa); diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h index cebd7d2016c8e..a959299d8ca6a 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h @@ -105,7 +105,7 @@ class XtensaTargetLowering : public TargetLowering { bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl &Outs, - LLVMContext &Context) const override; + LLVMContext &Context, const Type *RetTy) const override; SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index a0c0080c0bda1..0d8f52e12d5e4 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -136,23 +136,17 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level, unsigned Levels = D->getLevels(); char Direction; for (unsigned II = 1; II <= Levels; ++II) { - if (D->isScalar(II)) { - Direction = 'S'; - Dep.push_back(Direction); - } else { - unsigned Dir = D->getDirection(II); - if (Dir == Dependence::DVEntry::LT || - Dir == Dependence::DVEntry::LE) - Direction = '<'; - else if (Dir == Dependence::DVEntry::GT || - Dir == Dependence::DVEntry::GE) - Direction = '>'; - else if (Dir == Dependence::DVEntry::EQ) - Direction = '='; - else - Direction = '*'; - Dep.push_back(Direction); - } + unsigned Dir = D->getDirection(II); + if (Dir == Dependence::DVEntry::LT || Dir == Dependence::DVEntry::LE) + Direction = '<'; + else if (Dir == Dependence::DVEntry::GT || + Dir == Dependence::DVEntry::GE) + Direction = '>'; + else if (Dir == Dependence::DVEntry::EQ) + Direction = '='; + else + Direction = '*'; + Dep.push_back(Direction); } while (Dep.size() != Level) { Dep.push_back('I'); diff --git a/llvm/test/CodeGen/AArch64/vector-extract-last-active.ll b/llvm/test/CodeGen/AArch64/vector-extract-last-active.ll index 5212acc6fca0f..3b11e67d072e7 100644 --- a/llvm/test/CodeGen/AArch64/vector-extract-last-active.ll +++ b/llvm/test/CodeGen/AArch64/vector-extract-last-active.ll @@ -318,7 +318,7 @@ define i16 @extract_last_i16_scalable( %data, %data, %data, %data, %data, %data, %data, %mask) #0 { +; CHECK-LABEL: extract_last_i8_scalable_poison_passthru: +; CHECK: // %bb.0: +; CHECK-NEXT: index z1.b, #0, #1 +; CHECK-NEXT: mov z2.b, #0 // =0x0 +; CHECK-NEXT: sel z1.b, p0, z1.b, z2.b +; CHECK-NEXT: ptrue p0.b +; CHECK-NEXT: umaxv b1, p0, z1.b +; CHECK-NEXT: fmov w8, s1 +; CHECK-NEXT: and x8, x8, #0xff +; CHECK-NEXT: whilels p0.b, xzr, x8 +; CHECK-NEXT: lastb w0, p0, z0.b +; CHECK-NEXT: ret + %res = call i8 @llvm.experimental.vector.extract.last.active.nxv16i8( %data, %mask, i8 poison) + ret i8 %res +} + declare i8 @llvm.experimental.vector.extract.last.active.v16i8(<16 x i8>, <16 x i1>, i8) declare i16 @llvm.experimental.vector.extract.last.active.v8i16(<8 x i16>, <8 x i1>, i16) declare i32 @llvm.experimental.vector.extract.last.active.v4i32(<4 x i32>, <4 x i1>, i32) diff --git a/llvm/test/CodeGen/AMDGPU/lower-term-opcodes.mir b/llvm/test/CodeGen/AMDGPU/lower-term-opcodes.mir index 8fb3e9ea3609b..acc9bf78a3401 100644 --- a/llvm/test/CodeGen/AMDGPU/lower-term-opcodes.mir +++ b/llvm/test/CodeGen/AMDGPU/lower-term-opcodes.mir @@ -2,6 +2,8 @@ # RUN: llc -mtriple=amdgcn -mcpu=gfx1010 -run-pass=si-optimize-exec-masking -verify-machineinstrs %s -o - | FileCheck %s # RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -run-pass=si-optimize-exec-masking -verify-machineinstrs %s -o - | FileCheck %s +# RUN: llc -mtriple=amdgcn -mcpu=gfx1010 -passes=si-optimize-exec-masking -verify-machineinstrs %s -o - | FileCheck %s +# RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -passes=si-optimize-exec-masking -verify-machineinstrs %s -o - | FileCheck %s --- name: lower_term_opcodes tracksRegLiveness: false diff --git a/llvm/test/CodeGen/AMDGPU/optimize-exec-copies-extra-insts-after-copy.mir b/llvm/test/CodeGen/AMDGPU/optimize-exec-copies-extra-insts-after-copy.mir index ada5cfd5668ee..f2534a93da302 100644 --- a/llvm/test/CodeGen/AMDGPU/optimize-exec-copies-extra-insts-after-copy.mir +++ b/llvm/test/CodeGen/AMDGPU/optimize-exec-copies-extra-insts-after-copy.mir @@ -1,5 +1,6 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -mtriple=amdgcn -mcpu=fiji -verify-machineinstrs -run-pass=si-optimize-exec-masking -o - %s | FileCheck %s +# RUN: llc -mtriple=amdgcn -mcpu=fiji -verify-machineinstrs -passes=si-optimize-exec-masking -o - %s | FileCheck %s # Make sure we can still optimize writes to exec when there are # additional terminators after the exec write. This can happen with diff --git a/llvm/test/CodeGen/Mips/mips64-f128.ll b/llvm/test/CodeGen/Mips/mips64-f128.ll index ac29154579c50..04bed7d42bf96 100644 --- a/llvm/test/CodeGen/Mips/mips64-f128.ll +++ b/llvm/test/CodeGen/Mips/mips64-f128.ll @@ -2903,6 +2903,242 @@ entry: %cond = select i1 %cmp, fp128 %c, fp128 %d ret fp128 %cond } + +define { i8, i128 } @bar_structure_without_fp128() nounwind { +; C_CC_FMT-LABEL: bar_structure_without_fp128: +; C_CC_FMT: # %bb.0: # %entry +; C_CC_FMT-NEXT: sd $zero, 24($4) +; C_CC_FMT-NEXT: sd $zero, 16($4) +; C_CC_FMT-NEXT: sb $zero, 0($4) +; C_CC_FMT-NEXT: jr $ra +; C_CC_FMT-NEXT: nop +; +; CMP_CC_FMT-LABEL: bar_structure_without_fp128: +; CMP_CC_FMT: # %bb.0: # %entry +; CMP_CC_FMT-NEXT: sd $zero, 24($4) +; CMP_CC_FMT-NEXT: sd $zero, 16($4) +; CMP_CC_FMT-NEXT: sb $zero, 0($4) +; CMP_CC_FMT-NEXT: jrc $ra +entry: + ret { i8, i128 } zeroinitializer +} + +define fp128 @call_structure_without_fp128() nounwind { +; C_CC_FMT-LABEL: call_structure_without_fp128: +; C_CC_FMT: # %bb.0: # %entry +; C_CC_FMT-NEXT: daddiu $sp, $sp, -48 +; C_CC_FMT-NEXT: sd $ra, 40($sp) # 8-byte Folded Spill +; C_CC_FMT-NEXT: sd $gp, 32($sp) # 8-byte Folded Spill +; C_CC_FMT-NEXT: lui $1, %hi(%neg(%gp_rel(call_structure_without_fp128))) +; C_CC_FMT-NEXT: daddu $1, $1, $25 +; C_CC_FMT-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(call_structure_without_fp128))) +; C_CC_FMT-NEXT: daddiu $4, $sp, 0 +; C_CC_FMT-NEXT: ld $25, %call16(bar_structure_without_fp128)($gp) +; C_CC_FMT-NEXT: .reloc .Ltmp51, R_MIPS_JALR, bar_structure_without_fp128 +; C_CC_FMT-NEXT: .Ltmp51: +; C_CC_FMT-NEXT: jalr $25 +; C_CC_FMT-NEXT: nop +; C_CC_FMT-NEXT: daddiu $2, $zero, 0 +; C_CC_FMT-NEXT: daddiu $4, $zero, 0 +; C_CC_FMT-NEXT: ld $gp, 32($sp) # 8-byte Folded Reload +; C_CC_FMT-NEXT: ld $ra, 40($sp) # 8-byte Folded Reload +; C_CC_FMT-NEXT: daddiu $sp, $sp, 48 +; C_CC_FMT-NEXT: jr $ra +; C_CC_FMT-NEXT: nop +; +; CMP_CC_FMT-LABEL: call_structure_without_fp128: +; CMP_CC_FMT: # %bb.0: # %entry +; CMP_CC_FMT-NEXT: daddiu $sp, $sp, -48 +; CMP_CC_FMT-NEXT: sd $ra, 40($sp) # 8-byte Folded Spill +; CMP_CC_FMT-NEXT: sd $gp, 32($sp) # 8-byte Folded Spill +; CMP_CC_FMT-NEXT: lui $1, %hi(%neg(%gp_rel(call_structure_without_fp128))) +; CMP_CC_FMT-NEXT: daddu $1, $1, $25 +; CMP_CC_FMT-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(call_structure_without_fp128))) +; CMP_CC_FMT-NEXT: daddiu $4, $sp, 0 +; CMP_CC_FMT-NEXT: ld $25, %call16(bar_structure_without_fp128)($gp) +; CMP_CC_FMT-NEXT: .reloc .Ltmp51, R_MIPS_JALR, bar_structure_without_fp128 +; CMP_CC_FMT-NEXT: .Ltmp51: +; CMP_CC_FMT-NEXT: jalrc $25 +; CMP_CC_FMT-NEXT: daddiu $2, $zero, 0 +; CMP_CC_FMT-NEXT: daddiu $4, $zero, 0 +; CMP_CC_FMT-NEXT: ld $gp, 32($sp) # 8-byte Folded Reload +; CMP_CC_FMT-NEXT: ld $ra, 40($sp) # 8-byte Folded Reload +; CMP_CC_FMT-NEXT: daddiu $sp, $sp, 48 +; CMP_CC_FMT-NEXT: jrc $ra +entry: + call { i8, i128 } @bar_structure_without_fp128() + ret fp128 0xL00000000000000000000000000000000 +} + +define { fp128 } @bar_structure_fp128() nounwind { +; C_CC_FMT-LABEL: bar_structure_fp128: +; C_CC_FMT: # %bb.0: # %entry +; C_CC_FMT-NEXT: daddiu $2, $zero, 0 +; C_CC_FMT-NEXT: daddiu $4, $zero, 0 +; C_CC_FMT-NEXT: jr $ra +; C_CC_FMT-NEXT: nop +; +; CMP_CC_FMT-LABEL: bar_structure_fp128: +; CMP_CC_FMT: # %bb.0: # %entry +; CMP_CC_FMT-NEXT: daddiu $2, $zero, 0 +; CMP_CC_FMT-NEXT: daddiu $4, $zero, 0 +; CMP_CC_FMT-NEXT: jrc $ra +entry: + ret { fp128 } zeroinitializer +} + +define fp128 @tail_call_structure_fp128() nounwind { +; C_CC_FMT-LABEL: tail_call_structure_fp128: +; C_CC_FMT: # %bb.0: # %entry +; C_CC_FMT-NEXT: daddiu $sp, $sp, -16 +; C_CC_FMT-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill +; C_CC_FMT-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill +; C_CC_FMT-NEXT: lui $1, %hi(%neg(%gp_rel(tail_call_structure_fp128))) +; C_CC_FMT-NEXT: daddu $1, $1, $25 +; C_CC_FMT-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(tail_call_structure_fp128))) +; C_CC_FMT-NEXT: ld $25, %call16(bar_structure_fp128)($gp) +; C_CC_FMT-NEXT: .reloc .Ltmp52, R_MIPS_JALR, bar_structure_fp128 +; C_CC_FMT-NEXT: .Ltmp52: +; C_CC_FMT-NEXT: jalr $25 +; C_CC_FMT-NEXT: nop +; C_CC_FMT-NEXT: daddiu $2, $zero, 0 +; C_CC_FMT-NEXT: daddiu $4, $zero, 0 +; C_CC_FMT-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload +; C_CC_FMT-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload +; C_CC_FMT-NEXT: daddiu $sp, $sp, 16 +; C_CC_FMT-NEXT: jr $ra +; C_CC_FMT-NEXT: nop +; +; CMP_CC_FMT-LABEL: tail_call_structure_fp128: +; CMP_CC_FMT: # %bb.0: # %entry +; CMP_CC_FMT-NEXT: daddiu $sp, $sp, -16 +; CMP_CC_FMT-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill +; CMP_CC_FMT-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill +; CMP_CC_FMT-NEXT: lui $1, %hi(%neg(%gp_rel(tail_call_structure_fp128))) +; CMP_CC_FMT-NEXT: daddu $1, $1, $25 +; CMP_CC_FMT-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(tail_call_structure_fp128))) +; CMP_CC_FMT-NEXT: ld $25, %call16(bar_structure_fp128)($gp) +; CMP_CC_FMT-NEXT: .reloc .Ltmp52, R_MIPS_JALR, bar_structure_fp128 +; CMP_CC_FMT-NEXT: .Ltmp52: +; CMP_CC_FMT-NEXT: jalrc $25 +; CMP_CC_FMT-NEXT: daddiu $2, $zero, 0 +; CMP_CC_FMT-NEXT: daddiu $4, $zero, 0 +; CMP_CC_FMT-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload +; CMP_CC_FMT-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload +; CMP_CC_FMT-NEXT: daddiu $sp, $sp, 16 +; CMP_CC_FMT-NEXT: jrc $ra +entry: + %call = tail call fp128 @bar_structure_fp128() + ret fp128 0xL00000000000000000000000000000000 +} + +define fp128 @bar_fp128() nounwind { +; C_CC_FMT-LABEL: bar_fp128: +; C_CC_FMT: # %bb.0: # %entry +; C_CC_FMT-NEXT: daddiu $2, $zero, 0 +; C_CC_FMT-NEXT: daddiu $4, $zero, 0 +; C_CC_FMT-NEXT: jr $ra +; C_CC_FMT-NEXT: nop +; +; CMP_CC_FMT-LABEL: bar_fp128: +; CMP_CC_FMT: # %bb.0: # %entry +; CMP_CC_FMT-NEXT: daddiu $2, $zero, 0 +; CMP_CC_FMT-NEXT: daddiu $4, $zero, 0 +; CMP_CC_FMT-NEXT: jrc $ra +entry: + ret fp128 zeroinitializer +} + +define fp128 @call_fp128() nounwind { +; C_CC_FMT-LABEL: call_fp128: +; C_CC_FMT: # %bb.0: # %entry +; C_CC_FMT-NEXT: daddiu $sp, $sp, -16 +; C_CC_FMT-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill +; C_CC_FMT-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill +; C_CC_FMT-NEXT: lui $1, %hi(%neg(%gp_rel(call_fp128))) +; C_CC_FMT-NEXT: daddu $1, $1, $25 +; C_CC_FMT-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(call_fp128))) +; C_CC_FMT-NEXT: ld $25, %call16(bar_fp128)($gp) +; C_CC_FMT-NEXT: .reloc .Ltmp53, R_MIPS_JALR, bar_fp128 +; C_CC_FMT-NEXT: .Ltmp53: +; C_CC_FMT-NEXT: jalr $25 +; C_CC_FMT-NEXT: nop +; C_CC_FMT-NEXT: daddiu $2, $zero, 0 +; C_CC_FMT-NEXT: daddiu $4, $zero, 0 +; C_CC_FMT-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload +; C_CC_FMT-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload +; C_CC_FMT-NEXT: daddiu $sp, $sp, 16 +; C_CC_FMT-NEXT: jr $ra +; C_CC_FMT-NEXT: nop +; +; CMP_CC_FMT-LABEL: call_fp128: +; CMP_CC_FMT: # %bb.0: # %entry +; CMP_CC_FMT-NEXT: daddiu $sp, $sp, -16 +; CMP_CC_FMT-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill +; CMP_CC_FMT-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill +; CMP_CC_FMT-NEXT: lui $1, %hi(%neg(%gp_rel(call_fp128))) +; CMP_CC_FMT-NEXT: daddu $1, $1, $25 +; CMP_CC_FMT-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(call_fp128))) +; CMP_CC_FMT-NEXT: ld $25, %call16(bar_fp128)($gp) +; CMP_CC_FMT-NEXT: .reloc .Ltmp53, R_MIPS_JALR, bar_fp128 +; CMP_CC_FMT-NEXT: .Ltmp53: +; CMP_CC_FMT-NEXT: jalrc $25 +; CMP_CC_FMT-NEXT: daddiu $2, $zero, 0 +; CMP_CC_FMT-NEXT: daddiu $4, $zero, 0 +; CMP_CC_FMT-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload +; CMP_CC_FMT-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload +; CMP_CC_FMT-NEXT: daddiu $sp, $sp, 16 +; CMP_CC_FMT-NEXT: jrc $ra +entry: + call fp128 @bar_fp128() + ret fp128 0xL00000000000000000000000000000000 +} + +define fp128 @call_structure_fp128() nounwind { +; C_CC_FMT-LABEL: call_structure_fp128: +; C_CC_FMT: # %bb.0: # %entry +; C_CC_FMT-NEXT: daddiu $sp, $sp, -16 +; C_CC_FMT-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill +; C_CC_FMT-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill +; C_CC_FMT-NEXT: lui $1, %hi(%neg(%gp_rel(call_structure_fp128))) +; C_CC_FMT-NEXT: daddu $1, $1, $25 +; C_CC_FMT-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(call_structure_fp128))) +; C_CC_FMT-NEXT: ld $25, %call16(bar_structure_fp128)($gp) +; C_CC_FMT-NEXT: .reloc .Ltmp54, R_MIPS_JALR, bar_structure_fp128 +; C_CC_FMT-NEXT: .Ltmp54: +; C_CC_FMT-NEXT: jalr $25 +; C_CC_FMT-NEXT: nop +; C_CC_FMT-NEXT: daddiu $2, $zero, 0 +; C_CC_FMT-NEXT: daddiu $4, $zero, 0 +; C_CC_FMT-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload +; C_CC_FMT-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload +; C_CC_FMT-NEXT: daddiu $sp, $sp, 16 +; C_CC_FMT-NEXT: jr $ra +; C_CC_FMT-NEXT: nop +; +; CMP_CC_FMT-LABEL: call_structure_fp128: +; CMP_CC_FMT: # %bb.0: # %entry +; CMP_CC_FMT-NEXT: daddiu $sp, $sp, -16 +; CMP_CC_FMT-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill +; CMP_CC_FMT-NEXT: sd $gp, 0($sp) # 8-byte Folded Spill +; CMP_CC_FMT-NEXT: lui $1, %hi(%neg(%gp_rel(call_structure_fp128))) +; CMP_CC_FMT-NEXT: daddu $1, $1, $25 +; CMP_CC_FMT-NEXT: daddiu $gp, $1, %lo(%neg(%gp_rel(call_structure_fp128))) +; CMP_CC_FMT-NEXT: ld $25, %call16(bar_structure_fp128)($gp) +; CMP_CC_FMT-NEXT: .reloc .Ltmp54, R_MIPS_JALR, bar_structure_fp128 +; CMP_CC_FMT-NEXT: .Ltmp54: +; CMP_CC_FMT-NEXT: jalrc $25 +; CMP_CC_FMT-NEXT: daddiu $2, $zero, 0 +; CMP_CC_FMT-NEXT: daddiu $4, $zero, 0 +; CMP_CC_FMT-NEXT: ld $gp, 0($sp) # 8-byte Folded Reload +; CMP_CC_FMT-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload +; CMP_CC_FMT-NEXT: daddiu $sp, $sp, 16 +; CMP_CC_FMT-NEXT: jrc $ra +entry: + call { fp128 } @bar_structure_fp128() + ret fp128 0xL00000000000000000000000000000000 +} + ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: ; ALL: {{.*}} ; PRER6: {{.*}} diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-extract-last-active.ll b/llvm/test/CodeGen/RISCV/rvv/vector-extract-last-active.ll index 1eef183db21bb..10929394af75f 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vector-extract-last-active.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vector-extract-last-active.ll @@ -189,79 +189,43 @@ define i8 @extract_last_i8_scalable( %data, } define i16 @extract_last_i16_scalable( %data, %mask, i16 %passthru) { -; RV32-LABEL: extract_last_i16_scalable: -; RV32: # %bb.0: -; RV32-NEXT: vsetvli a1, zero, e16, m2, ta, mu -; RV32-NEXT: vmv.v.i v10, 0 -; RV32-NEXT: vcpop.m a1, v0 -; RV32-NEXT: vid.v v10, v0.t -; RV32-NEXT: beqz a1, .LBB7_2 -; RV32-NEXT: # %bb.1: -; RV32-NEXT: vredmaxu.vs v10, v10, v10 -; RV32-NEXT: vmv.x.s a0, v10 -; RV32-NEXT: slli a0, a0, 16 -; RV32-NEXT: srli a0, a0, 16 -; RV32-NEXT: vsetvli zero, zero, e16, m2, ta, ma -; RV32-NEXT: vslidedown.vx v8, v8, a0 -; RV32-NEXT: vmv.x.s a0, v8 -; RV32-NEXT: .LBB7_2: -; RV32-NEXT: ret -; -; RV64-LABEL: extract_last_i16_scalable: -; RV64: # %bb.0: -; RV64-NEXT: vsetvli a1, zero, e16, m2, ta, mu -; RV64-NEXT: vmv.v.i v10, 0 -; RV64-NEXT: vcpop.m a1, v0 -; RV64-NEXT: vid.v v10, v0.t -; RV64-NEXT: beqz a1, .LBB7_2 -; RV64-NEXT: # %bb.1: -; RV64-NEXT: vredmaxu.vs v10, v10, v10 -; RV64-NEXT: vmv.x.s a0, v10 -; RV64-NEXT: slli a0, a0, 48 -; RV64-NEXT: srli a0, a0, 48 -; RV64-NEXT: vsetvli zero, zero, e16, m2, ta, ma -; RV64-NEXT: vslidedown.vx v8, v8, a0 -; RV64-NEXT: vmv.x.s a0, v8 -; RV64-NEXT: .LBB7_2: -; RV64-NEXT: ret +; CHECK-LABEL: extract_last_i16_scalable: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, mu +; CHECK-NEXT: vmv.v.i v10, 0 +; CHECK-NEXT: vcpop.m a1, v0 +; CHECK-NEXT: vid.v v10, v0.t +; CHECK-NEXT: beqz a1, .LBB7_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: vredmaxu.vs v10, v10, v10 +; CHECK-NEXT: vmv.x.s a0, v10 +; CHECK-NEXT: andi a0, a0, 255 +; CHECK-NEXT: vsetvli zero, zero, e16, m2, ta, ma +; CHECK-NEXT: vslidedown.vx v8, v8, a0 +; CHECK-NEXT: vmv.x.s a0, v8 +; CHECK-NEXT: .LBB7_2: +; CHECK-NEXT: ret %res = call i16 @llvm.experimental.vector.extract.last.active.nxv8i16( %data, %mask, i16 %passthru) ret i16 %res } define i32 @extract_last_i32_scalable( %data, %mask, i32 %passthru) { -; RV32-LABEL: extract_last_i32_scalable: -; RV32: # %bb.0: -; RV32-NEXT: vsetvli a1, zero, e32, m2, ta, mu -; RV32-NEXT: vmv.v.i v10, 0 -; RV32-NEXT: vcpop.m a1, v0 -; RV32-NEXT: vid.v v10, v0.t -; RV32-NEXT: beqz a1, .LBB8_2 -; RV32-NEXT: # %bb.1: -; RV32-NEXT: vredmaxu.vs v10, v10, v10 -; RV32-NEXT: vmv.x.s a0, v10 -; RV32-NEXT: vsetvli zero, zero, e32, m2, ta, ma -; RV32-NEXT: vslidedown.vx v8, v8, a0 -; RV32-NEXT: vmv.x.s a0, v8 -; RV32-NEXT: .LBB8_2: -; RV32-NEXT: ret -; -; RV64-LABEL: extract_last_i32_scalable: -; RV64: # %bb.0: -; RV64-NEXT: vsetvli a1, zero, e32, m2, ta, mu -; RV64-NEXT: vmv.v.i v10, 0 -; RV64-NEXT: vcpop.m a1, v0 -; RV64-NEXT: vid.v v10, v0.t -; RV64-NEXT: beqz a1, .LBB8_2 -; RV64-NEXT: # %bb.1: -; RV64-NEXT: vredmaxu.vs v10, v10, v10 -; RV64-NEXT: vmv.x.s a0, v10 -; RV64-NEXT: slli a0, a0, 32 -; RV64-NEXT: srli a0, a0, 32 -; RV64-NEXT: vsetvli zero, zero, e32, m2, ta, ma -; RV64-NEXT: vslidedown.vx v8, v8, a0 -; RV64-NEXT: vmv.x.s a0, v8 -; RV64-NEXT: .LBB8_2: -; RV64-NEXT: ret +; CHECK-LABEL: extract_last_i32_scalable: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e8, mf2, ta, mu +; CHECK-NEXT: vmv.v.i v10, 0 +; CHECK-NEXT: vcpop.m a1, v0 +; CHECK-NEXT: vid.v v10, v0.t +; CHECK-NEXT: beqz a1, .LBB8_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: vredmaxu.vs v10, v10, v10 +; CHECK-NEXT: vmv.x.s a0, v10 +; CHECK-NEXT: andi a0, a0, 255 +; CHECK-NEXT: vsetvli zero, zero, e32, m2, ta, ma +; CHECK-NEXT: vslidedown.vx v8, v8, a0 +; CHECK-NEXT: vmv.x.s a0, v8 +; CHECK-NEXT: .LBB8_2: +; CHECK-NEXT: ret %res = call i32 @llvm.experimental.vector.extract.last.active.nxv4i32( %data, %mask, i32 %passthru) ret i32 %res } @@ -269,7 +233,7 @@ define i32 @extract_last_i32_scalable( %data, %data, %mask, i64 %passthru) { ; RV32-LABEL: extract_last_i64_scalable: ; RV32: # %bb.0: -; RV32-NEXT: vsetvli a2, zero, e64, m2, ta, mu +; RV32-NEXT: vsetvli a2, zero, e8, mf4, ta, mu ; RV32-NEXT: vmv.v.i v10, 0 ; RV32-NEXT: vcpop.m a2, v0 ; RV32-NEXT: vid.v v10, v0.t @@ -278,6 +242,7 @@ define i64 @extract_last_i64_scalable( %data, %data, %data, %data, %data, %mask, float %passthru) { -; RV32-LABEL: extract_last_float_scalable: -; RV32: # %bb.0: -; RV32-NEXT: vsetvli a0, zero, e32, m2, ta, mu -; RV32-NEXT: vmv.v.i v10, 0 -; RV32-NEXT: vcpop.m a0, v0 -; RV32-NEXT: vid.v v10, v0.t -; RV32-NEXT: beqz a0, .LBB10_2 -; RV32-NEXT: # %bb.1: -; RV32-NEXT: vredmaxu.vs v10, v10, v10 -; RV32-NEXT: vmv.x.s a0, v10 -; RV32-NEXT: vsetvli zero, zero, e32, m2, ta, ma -; RV32-NEXT: vslidedown.vx v8, v8, a0 -; RV32-NEXT: vfmv.f.s fa0, v8 -; RV32-NEXT: .LBB10_2: -; RV32-NEXT: ret -; -; RV64-LABEL: extract_last_float_scalable: -; RV64: # %bb.0: -; RV64-NEXT: vsetvli a0, zero, e32, m2, ta, mu -; RV64-NEXT: vmv.v.i v10, 0 -; RV64-NEXT: vcpop.m a0, v0 -; RV64-NEXT: vid.v v10, v0.t -; RV64-NEXT: beqz a0, .LBB10_2 -; RV64-NEXT: # %bb.1: -; RV64-NEXT: vredmaxu.vs v10, v10, v10 -; RV64-NEXT: vmv.x.s a0, v10 -; RV64-NEXT: slli a0, a0, 32 -; RV64-NEXT: srli a0, a0, 32 -; RV64-NEXT: vsetvli zero, zero, e32, m2, ta, ma -; RV64-NEXT: vslidedown.vx v8, v8, a0 -; RV64-NEXT: vfmv.f.s fa0, v8 -; RV64-NEXT: .LBB10_2: -; RV64-NEXT: ret +; CHECK-LABEL: extract_last_float_scalable: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e8, mf2, ta, mu +; CHECK-NEXT: vmv.v.i v10, 0 +; CHECK-NEXT: vcpop.m a0, v0 +; CHECK-NEXT: vid.v v10, v0.t +; CHECK-NEXT: beqz a0, .LBB10_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: vredmaxu.vs v10, v10, v10 +; CHECK-NEXT: vmv.x.s a0, v10 +; CHECK-NEXT: andi a0, a0, 255 +; CHECK-NEXT: vsetvli zero, zero, e32, m2, ta, ma +; CHECK-NEXT: vslidedown.vx v8, v8, a0 +; CHECK-NEXT: vfmv.f.s fa0, v8 +; CHECK-NEXT: .LBB10_2: +; CHECK-NEXT: ret %res = call float @llvm.experimental.vector.extract.last.active.nxv4f32( %data, %mask, float %passthru) ret float %res } @@ -347,7 +296,7 @@ define float @extract_last_float_scalable( %data, %data, %mask, double %passthru) { ; CHECK-LABEL: extract_last_double_scalable: ; CHECK: # %bb.0: -; CHECK-NEXT: vsetvli a0, zero, e64, m2, ta, mu +; CHECK-NEXT: vsetvli a0, zero, e8, mf4, ta, mu ; CHECK-NEXT: vmv.v.i v10, 0 ; CHECK-NEXT: vcpop.m a0, v0 ; CHECK-NEXT: vid.v v10, v0.t @@ -355,6 +304,7 @@ define double @extract_last_double_scalable( %data, &1 | FileCheck -check-prefix=IR %s ; RUN: FileCheck --input-file=%t %s -; Inner loop only reductions are not supported currently. See discussion at -; D53027 for more information on the required checks. +; Both tests should be rejected as interchange candidates. For now, they are +; rejected for dependence analysis reasons, but that's because support for 'S' +; scalar dependencies was removed. When that is properly, the inner loop only +; reductions should still not be supported currently, see discussion at D53027 +; for more information on the required checks. @A = common global [500 x [500 x i32]] zeroinitializer @X = common global i32 0 @@ -18,7 +21,7 @@ ; CHECK: --- !Missed ; CHECK-NEXT: Pass: loop-interchange -; CHECK-NEXT: Name: UnsupportedPHI +; CHECK-NEXT: Name: Dependence ; CHECK-NEXT: Function: reduction_01 ; IR-LABEL: @reduction_01( @@ -71,7 +74,7 @@ for.end8: ; preds = %for.cond1.for.inc6_ ; CHECK: --- !Missed ; CHECK-NEXT: Pass: loop-interchange -; CHECK-NEXT: Name: UnsupportedPHIOuter +; CHECK-NEXT: Name: Dependence ; CHECK-NEXT: Function: reduction_03 ; IR-LABEL: @reduction_03( diff --git a/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll b/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll index 230f7dc2bcfad..da37395372e5f 100644 --- a/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll +++ b/llvm/test/Transforms/LoopInterchange/innermost-latch-uses-values-in-middle-header.ll @@ -1,3 +1,11 @@ +; Remove 'S' Scalar Dependencies #119345 +; Scalar dependencies are not handled correctly, so they were removed to avoid +; miscompiles. The loop nest in this test case used to be interchanged, but it's +; no longer triggering. XFAIL'ing this test to indicate that this test should +; interchanged if scalar deps are handled correctly. +; +; XFAIL: * + ; RUN: opt < %s -passes=loop-interchange -verify-dom-info -verify-loop-info -pass-remarks-output=%t -disable-output ; RUN: FileCheck -input-file %t %s diff --git a/llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll b/llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll index a208c1f46a705..77ab845846bd6 100644 --- a/llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll +++ b/llvm/test/Transforms/LoopInterchange/interchange-flow-dep-outer.ll @@ -1,3 +1,11 @@ +; Remove 'S' Scalar Dependencies #119345 +; Scalar dependencies are not handled correctly, so they were removed to avoid +; miscompiles. The loop nest in this test case used to be interchanged, but it's +; no longer triggering. XFAIL'ing this test to indicate that this test should +; interchanged if scalar deps are handled correctly. +; +; XFAIL: * + ; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info -pass-remarks-output=%t -disable-output ; RUN: FileCheck -input-file %t %s diff --git a/llvm/test/Transforms/LoopInterchange/lcssa.ll b/llvm/test/Transforms/LoopInterchange/lcssa.ll index 0a5aefd9e4911..e77efe3052b40 100644 --- a/llvm/test/Transforms/LoopInterchange/lcssa.ll +++ b/llvm/test/Transforms/LoopInterchange/lcssa.ll @@ -1,3 +1,11 @@ +; Remove 'S' Scalar Dependencies #119345 +; Scalar dependencies are not handled correctly, so they were removed to avoid +; miscompiles. The loop nest in this test case used to be interchanged, but it's +; no longer triggering. XFAIL'ing this test to indicate that this test should +; interchanged if scalar deps are handled correctly. +; +; XFAIL: * + ; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-missed='loop-interchange' -verify-loop-lcssa -pass-remarks-output=%t -S ; RUN: FileCheck --input-file %t --check-prefix REMARK %s @@ -177,7 +185,7 @@ for.end16: ; preds = %for.exit } ; PHI node in inner latch with multiple predecessors. -; REMARK: Interchanged +; REMARK: Interchanged ; REMARK-NEXT: lcssa_05 define void @lcssa_05(ptr %ptr, i1 %arg) { @@ -222,7 +230,7 @@ for.end16: ; preds = %for.exit ret void } -; REMARK: UnsupportedExitPHI +; REMARK: UnsupportedExitPHI ; REMARK-NEXT: lcssa_06 define void @lcssa_06(ptr %ptr, ptr %ptr1, i1 %arg) { diff --git a/llvm/test/Transforms/LoopInterchange/outer-header-jump-to-inner-latch.ll b/llvm/test/Transforms/LoopInterchange/outer-header-jump-to-inner-latch.ll index aaf8b1daf0414..5ee1bddbe23fc 100644 --- a/llvm/test/Transforms/LoopInterchange/outer-header-jump-to-inner-latch.ll +++ b/llvm/test/Transforms/LoopInterchange/outer-header-jump-to-inner-latch.ll @@ -1,3 +1,11 @@ +; Remove 'S' Scalar Dependencies #119345 +; Scalar dependencies are not handled correctly, so they were removed to avoid +; miscompiles. The loop nest in this test case used to be interchanged, but it's +; no longer triggering. XFAIL'ing this test to indicate that this test should +; interchanged if scalar deps are handled correctly. +; +; XFAIL: * + ; RUN: opt -passes=loop-interchange -cache-line-size=64 -verify-dom-info -verify-loop-info -verify-loop-lcssa %s -pass-remarks-output=%t -disable-output ; RUN: FileCheck -input-file %t %s diff --git a/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll b/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll index 9d2e393937bd5..6b25c3bc9a4ba 100644 --- a/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll +++ b/llvm/test/Transforms/LoopInterchange/pr43176-move-to-new-latch.ll @@ -14,10 +14,10 @@ ; CHECK: --- !Missed ; CHECK-NEXT: Pass: loop-interchange -; CHECK-NEXT: Name: InterchangeNotProfitable +; CHECK-NEXT: Name: Dependence ; CHECK-NEXT: Function: test1 ; CHECK-NEXT: Args: -; CHECK-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization. +; CHECK-NEXT: - String: Cannot interchange loops due to dependences. define void @test1() { entry: @@ -54,10 +54,10 @@ for.cond.for.end5_crit_edge: ; preds = %for.inc3 ; CHECK: --- !Missed ; CHECK-NEXT: Pass: loop-interchange -; CHECK-NEXT: Name: InterchangeNotProfitable +; CHECK-NEXT: Name: Dependence ; CHECK-NEXT: Function: test2 ; CHECK-NEXT: Args: -; CHECK-NEXT: - String: Interchanging loops is not considered to improve cache locality nor vectorization. +; CHECK-NEXT: - String: Cannot interchange loops due to dependences. define void @test2() { entry: diff --git a/llvm/test/Transforms/LoopInterchange/pr43797-lcssa-for-multiple-outer-loop-blocks.ll b/llvm/test/Transforms/LoopInterchange/pr43797-lcssa-for-multiple-outer-loop-blocks.ll index 38970354c3d1c..51493d72a827d 100644 --- a/llvm/test/Transforms/LoopInterchange/pr43797-lcssa-for-multiple-outer-loop-blocks.ll +++ b/llvm/test/Transforms/LoopInterchange/pr43797-lcssa-for-multiple-outer-loop-blocks.ll @@ -1,3 +1,11 @@ +; Remove 'S' Scalar Dependencies #119345 +; Scalar dependencies are not handled correctly, so they were removed to avoid +; miscompiles. The loop nest in this test case used to be interchanged, but it's +; no longer triggering. XFAIL'ing this test to indicate that this test should +; interchanged if scalar deps are handled correctly. +; +; XFAIL: * + ; RUN: opt -passes=loop-interchange -cache-line-size=64 -verify-loop-lcssa %s -pass-remarks-output=%t -disable-output ; RUN: FileCheck -input-file %t %s diff --git a/llvm/test/Transforms/LoopInterchange/profitability.ll b/llvm/test/Transforms/LoopInterchange/profitability.ll index 505c6c422beb6..4804ecfc8ed6f 100644 --- a/llvm/test/Transforms/LoopInterchange/profitability.ll +++ b/llvm/test/Transforms/LoopInterchange/profitability.ll @@ -1,3 +1,11 @@ +; Remove 'S' Scalar Dependencies #119345 +; Scalar dependencies are not handled correctly, so they were removed to avoid +; miscompiles. The loop nest in this test case used to be interchanged, but it's +; no longer triggering. XFAIL'ing this test to indicate that this test should +; interchanged if scalar deps are handled correctly. +; +; XFAIL: * + ; RUN: opt < %s -passes=loop-interchange -cache-line-size=64 -pass-remarks-output=%t -verify-dom-info -verify-loop-info \ ; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange ; RUN: FileCheck -input-file %t %s diff --git a/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll b/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll index fa2021a15a080..eea0c2635d595 100644 --- a/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll +++ b/llvm/test/Transforms/LoopInterchange/reductions-across-inner-and-outer-loop.ll @@ -153,7 +153,7 @@ for1.loopexit: ; preds = %for1.inc ; Check that we do not interchange if reduction is stored in an invariant address inside inner loop ; REMARKS: --- !Missed ; REMARKS-NEXT: Pass: loop-interchange -; REMARKS-NEXT: Name: UnsupportedPHIOuter +; REMARKS-NEXT: Name: Dependence ; REMARKS-NEXT: Function: test4 define i64 @test4(ptr %Arr, ptr %dst) { diff --git a/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll b/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll index 6943e39cf163e..e5c18830784ac 100644 --- a/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll +++ b/llvm/test/Transforms/LoopInterchange/unique-dep-matrix.ll @@ -3,8 +3,8 @@ ; CHECK: Dependency matrix before interchange: ; CHECK-NEXT: I I -; CHECK-NEXT: = S -; CHECK-NEXT: < S +; CHECK-NEXT: = * +; CHECK-NEXT: < * ; CHECK-NEXT: Processing InnerLoopId ; This example is taken from github issue #54176 diff --git a/llvm/test/Transforms/LoopInterchange/vector-gep-operand.ll b/llvm/test/Transforms/LoopInterchange/vector-gep-operand.ll index 022cdd44b7f50..478042f6f3c4d 100644 --- a/llvm/test/Transforms/LoopInterchange/vector-gep-operand.ll +++ b/llvm/test/Transforms/LoopInterchange/vector-gep-operand.ll @@ -1,3 +1,11 @@ +; Remove 'S' Scalar Dependencies #119345 +; Scalar dependencies are not handled correctly, so they were removed to avoid +; miscompiles. The loop nest in this test case used to be interchanged, but it's +; no longer triggering. XFAIL'ing this test to indicate that this test should +; interchanged if scalar deps are handled correctly. +; +; XFAIL: * + ; RUN: opt -passes=loop-interchange -cache-line-size=64 -loop-interchange-threshold=-10 %s -pass-remarks-output=%t -disable-output ; RUN: FileCheck -input-file %t %s diff --git a/mlir/include/mlir/Conversion/MathToEmitC/MathToEmitC.h b/mlir/include/mlir/Conversion/MathToEmitC/MathToEmitC.h new file mode 100644 index 0000000000000..0fc33bf790be4 --- /dev/null +++ b/mlir/include/mlir/Conversion/MathToEmitC/MathToEmitC.h @@ -0,0 +1,25 @@ +//===- MathToEmitC.h - Math to EmitC Patterns -------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITC_H +#define MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITC_H +#include "mlir/Dialect/EmitC/IR/EmitC.h" +namespace mlir { +class RewritePatternSet; +namespace emitc { + +/// Enum to specify the language target for EmitC code generation. +enum class LanguageTarget { c99, cpp11 }; + +} // namespace emitc + +void populateConvertMathToEmitCPatterns(RewritePatternSet &patterns, + emitc::LanguageTarget languageTarget); +} // namespace mlir + +#endif // MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITC_H diff --git a/mlir/include/mlir/Conversion/MathToEmitC/MathToEmitCPass.h b/mlir/include/mlir/Conversion/MathToEmitC/MathToEmitCPass.h new file mode 100644 index 0000000000000..c3861db7764c3 --- /dev/null +++ b/mlir/include/mlir/Conversion/MathToEmitC/MathToEmitCPass.h @@ -0,0 +1,21 @@ +//===- MathToEmitCPass.h - Math to EmitC Pass -------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITCPASS_H +#define MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITCPASS_H + +#include "mlir/Conversion/MathToEmitC/MathToEmitC.h" +#include +namespace mlir { +class Pass; + +#define GEN_PASS_DECL_CONVERTMATHTOEMITC +#include "mlir/Conversion/Passes.h.inc" +} // namespace mlir + +#endif // MLIR_CONVERSION_MATHTOEMITC_MATHTOEMITCPASS_H diff --git a/mlir/include/mlir/Conversion/Passes.h b/mlir/include/mlir/Conversion/Passes.h index 035404a4c5e47..ea05a5937fa6a 100644 --- a/mlir/include/mlir/Conversion/Passes.h +++ b/mlir/include/mlir/Conversion/Passes.h @@ -43,6 +43,7 @@ #include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h" #include "mlir/Conversion/IndexToSPIRV/IndexToSPIRV.h" #include "mlir/Conversion/LinalgToStandard/LinalgToStandard.h" +#include "mlir/Conversion/MathToEmitC/MathToEmitCPass.h" #include "mlir/Conversion/MathToFuncs/MathToFuncs.h" #include "mlir/Conversion/MathToLLVM/MathToLLVM.h" #include "mlir/Conversion/MathToLibm/MathToLibm.h" diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td index 61f754d67dc13..86c04fa1dab17 100644 --- a/mlir/include/mlir/Conversion/Passes.td +++ b/mlir/include/mlir/Conversion/Passes.td @@ -796,6 +796,28 @@ def ConvertMathToSPIRV : Pass<"convert-math-to-spirv"> { let dependentDialects = ["spirv::SPIRVDialect"]; } +//===----------------------------------------------------------------------===// +// MathToEmitC +//===----------------------------------------------------------------------===// + +def ConvertMathToEmitC : Pass<"convert-math-to-emitc"> { + let summary = "Convert some Math operations to EmitC call_opaque operations"; + let description = [{ + This pass converts supported Math ops to `call_opaque` ops targeting libc/libm + functions. Unlike convert-math-to-funcs pass, converting to `call_opaque` ops + allows to overload the same function with different argument types. + }]; + let dependentDialects = ["emitc::EmitCDialect"]; + let options = [ + Option<"languageTarget", "language-target", "::mlir::emitc::LanguageTarget", + /*default=*/"::mlir::emitc::LanguageTarget::c99", "Select the language standard target for callees (c99 or cpp11).", + [{::llvm::cl::values( + clEnumValN(::mlir::emitc::LanguageTarget::c99, "c99", "c99"), + clEnumValN(::mlir::emitc::LanguageTarget::cpp11, "cpp11", "cpp11") + )}]> + ]; +} + //===----------------------------------------------------------------------===// // MathToFuncs //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/IR/BlockSupport.h b/mlir/include/mlir/IR/BlockSupport.h index ff508891ac2ff..292938e46c27e 100644 --- a/mlir/include/mlir/IR/BlockSupport.h +++ b/mlir/include/mlir/IR/BlockSupport.h @@ -110,9 +110,9 @@ class BlockRange final BlockRange(SuccessorRange successors); template , Arg>::value>> - BlockRange(Arg &&arg) + BlockRange(Arg &&arg LLVM_LIFETIME_BOUND) : BlockRange(ArrayRef(std::forward(arg))) {} - BlockRange(std::initializer_list blocks) + BlockRange(std::initializer_list blocks LLVM_LIFETIME_BOUND) : BlockRange(ArrayRef(blocks)) {} private: diff --git a/mlir/include/mlir/IR/Region.h b/mlir/include/mlir/IR/Region.h index 93fc9dbb430ee..22cb7037772dd 100644 --- a/mlir/include/mlir/IR/Region.h +++ b/mlir/include/mlir/IR/Region.h @@ -357,12 +357,12 @@ class RegionRange template >, Arg>::value>> - RegionRange(Arg &&arg) + RegionRange(Arg &&arg LLVM_LIFETIME_BOUND) : RegionRange(ArrayRef>(std::forward(arg))) { } template RegionRange( - Arg &&arg, + Arg &&arg LLVM_LIFETIME_BOUND, std::enable_if_t, Arg>::value> * = nullptr) : RegionRange(ArrayRef(std::forward(arg))) {} diff --git a/mlir/include/mlir/IR/TypeRange.h b/mlir/include/mlir/IR/TypeRange.h index 99fabab334f92..9c2fbb3884188 100644 --- a/mlir/include/mlir/IR/TypeRange.h +++ b/mlir/include/mlir/IR/TypeRange.h @@ -46,8 +46,9 @@ class TypeRange : public llvm::detail::indexed_accessor_range_base< values.end().getCurrent()))) {} template , Arg>::value>> - TypeRange(Arg &&arg) : TypeRange(ArrayRef(std::forward(arg))) {} - TypeRange(std::initializer_list types) + TypeRange(Arg &&arg LLVM_LIFETIME_BOUND) + : TypeRange(ArrayRef(std::forward(arg))) {} + TypeRange(std::initializer_list types LLVM_LIFETIME_BOUND) : TypeRange(ArrayRef(types)) {} private: diff --git a/mlir/include/mlir/IR/ValueRange.h b/mlir/include/mlir/IR/ValueRange.h index 4b421c08d8418..a807b77ad077f 100644 --- a/mlir/include/mlir/IR/ValueRange.h +++ b/mlir/include/mlir/IR/ValueRange.h @@ -391,9 +391,11 @@ class ValueRange final typename = std::enable_if_t< std::is_constructible, Arg>::value && !std::is_convertible::value>> - ValueRange(Arg &&arg) : ValueRange(ArrayRef(std::forward(arg))) {} - ValueRange(const Value &value) : ValueRange(&value, /*count=*/1) {} - ValueRange(const std::initializer_list &values) + ValueRange(Arg &&arg LLVM_LIFETIME_BOUND) + : ValueRange(ArrayRef(std::forward(arg))) {} + ValueRange(const Value &value LLVM_LIFETIME_BOUND) + : ValueRange(&value, /*count=*/1) {} + ValueRange(const std::initializer_list &values LLVM_LIFETIME_BOUND) : ValueRange(ArrayRef(values)) {} ValueRange(iterator_range values) : ValueRange(OperandRange(values)) {} diff --git a/mlir/lib/Conversion/CMakeLists.txt b/mlir/lib/Conversion/CMakeLists.txt index 00e417e0e637a..07ccf8e2dbba0 100644 --- a/mlir/lib/Conversion/CMakeLists.txt +++ b/mlir/lib/Conversion/CMakeLists.txt @@ -33,6 +33,7 @@ add_subdirectory(IndexToLLVM) add_subdirectory(IndexToSPIRV) add_subdirectory(LinalgToStandard) add_subdirectory(LLVMCommon) +add_subdirectory(MathToEmitC) add_subdirectory(MathToFuncs) add_subdirectory(MathToLibm) add_subdirectory(MathToLLVM) diff --git a/mlir/lib/Conversion/MathToEmitC/CMakeLists.txt b/mlir/lib/Conversion/MathToEmitC/CMakeLists.txt new file mode 100644 index 0000000000000..12a99c31e2ba5 --- /dev/null +++ b/mlir/lib/Conversion/MathToEmitC/CMakeLists.txt @@ -0,0 +1,19 @@ +add_mlir_conversion_library(MLIRMathToEmitC + MathToEmitC.cpp + MathToEmitCPass.cpp + + ADDITIONAL_HEADER_DIRS + ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/MathToEmitC + + DEPENDS + MLIRConversionPassIncGen + + LINK_COMPONENTS + Core + + LINK_LIBS PUBLIC + MLIREmitCDialect + MLIRMathDialect + MLIRPass + MLIRTransformUtils +) diff --git a/mlir/lib/Conversion/MathToEmitC/MathToEmitC.cpp b/mlir/lib/Conversion/MathToEmitC/MathToEmitC.cpp new file mode 100644 index 0000000000000..9a0651a5445e6 --- /dev/null +++ b/mlir/lib/Conversion/MathToEmitC/MathToEmitC.cpp @@ -0,0 +1,85 @@ +//===- MathToEmitC.cpp - Math to EmitC Patterns -----------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "mlir/Conversion/MathToEmitC/MathToEmitC.h" + +#include "mlir/Dialect/EmitC/IR/EmitC.h" +#include "mlir/Dialect/Math/IR/Math.h" +#include "mlir/Transforms/DialectConversion.h" + +using namespace mlir; + +namespace { +template +class LowerToEmitCCallOpaque : public OpRewritePattern { + std::string calleeStr; + emitc::LanguageTarget languageTarget; + +public: + LowerToEmitCCallOpaque(MLIRContext *context, std::string calleeStr, + emitc::LanguageTarget languageTarget) + : OpRewritePattern(context), calleeStr(std::move(calleeStr)), + languageTarget(languageTarget) {} + + LogicalResult matchAndRewrite(OpType op, + PatternRewriter &rewriter) const override; +}; + +template +LogicalResult LowerToEmitCCallOpaque::matchAndRewrite( + OpType op, PatternRewriter &rewriter) const { + if (!llvm::all_of(op->getOperandTypes(), + llvm::IsaPred) || + !llvm::all_of(op->getResultTypes(), + llvm::IsaPred)) + return rewriter.notifyMatchFailure( + op.getLoc(), + "expected all operands and results to be of type f32 or f64"); + std::string modifiedCalleeStr = calleeStr; + if (languageTarget == emitc::LanguageTarget::cpp11) { + modifiedCalleeStr = "std::" + calleeStr; + } else if (languageTarget == emitc::LanguageTarget::c99) { + auto operandType = op->getOperandTypes()[0]; + if (operandType.isF32()) + modifiedCalleeStr = calleeStr + "f"; + } + rewriter.replaceOpWithNewOp( + op, op.getType(), modifiedCalleeStr, op->getOperands()); + return success(); +} + +} // namespace + +// Populates patterns to replace `math` operations with `emitc.call_opaque`, +// using function names consistent with those in . +void mlir::populateConvertMathToEmitCPatterns( + RewritePatternSet &patterns, emitc::LanguageTarget languageTarget) { + auto *context = patterns.getContext(); + patterns.insert>(context, "floor", + languageTarget); + patterns.insert>(context, "round", + languageTarget); + patterns.insert>(context, "exp", + languageTarget); + patterns.insert>(context, "cos", + languageTarget); + patterns.insert>(context, "sin", + languageTarget); + patterns.insert>(context, "acos", + languageTarget); + patterns.insert>(context, "asin", + languageTarget); + patterns.insert>(context, "atan2", + languageTarget); + patterns.insert>(context, "ceil", + languageTarget); + patterns.insert>(context, "fabs", + languageTarget); + patterns.insert>(context, "pow", + languageTarget); +} diff --git a/mlir/lib/Conversion/MathToEmitC/MathToEmitCPass.cpp b/mlir/lib/Conversion/MathToEmitC/MathToEmitCPass.cpp new file mode 100644 index 0000000000000..87a27644210fa --- /dev/null +++ b/mlir/lib/Conversion/MathToEmitC/MathToEmitCPass.cpp @@ -0,0 +1,53 @@ +//===- MathToEmitCPass.cpp - Math to EmitC Pass -----------------*- 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 implements a pass to convert the Math dialect to the EmitC dialect. +// +//===----------------------------------------------------------------------===// + +#include "mlir/Conversion/MathToEmitC/MathToEmitCPass.h" +#include "mlir/Conversion/MathToEmitC/MathToEmitC.h" +#include "mlir/Dialect/EmitC/IR/EmitC.h" +#include "mlir/Dialect/Math/IR/Math.h" +#include "mlir/Pass/Pass.h" +#include "mlir/Transforms/DialectConversion.h" + +namespace mlir { +#define GEN_PASS_DEF_CONVERTMATHTOEMITC +#include "mlir/Conversion/Passes.h.inc" +} // namespace mlir + +using namespace mlir; +namespace { + +// Replaces Math operations with `emitc.call_opaque` operations. +struct ConvertMathToEmitC + : public impl::ConvertMathToEmitCBase { + using ConvertMathToEmitCBase::ConvertMathToEmitCBase; + +public: + void runOnOperation() final; +}; + +} // namespace + +void ConvertMathToEmitC::runOnOperation() { + ConversionTarget target(getContext()); + target.addLegalOp(); + + target.addIllegalOp(); + + RewritePatternSet patterns(&getContext()); + populateConvertMathToEmitCPatterns(patterns, languageTarget); + + if (failed( + applyPartialConversion(getOperation(), target, std::move(patterns)))) + signalPassFailure(); +} diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp index 79dd3e3069648..aab8d037cd8d2 100644 --- a/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp +++ b/mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp @@ -643,9 +643,9 @@ static Value handleByValArgument(OpBuilder &builder, Operation *callable, return argument; } uint64_t targetAlignment = std::max(requestedAlignment, minimumAlignment); - return handleByValArgumentInit(builder, func.getLoc(), argument, elementType, - dataLayout.getTypeSize(elementType), - targetAlignment); + return handleByValArgumentInit( + builder, argument.getLoc(), argument, elementType, + dataLayout.getTypeSize(elementType), targetAlignment); } namespace { diff --git a/mlir/test/Conversion/MathToEmitC/math-to-emitc-failed.mlir b/mlir/test/Conversion/MathToEmitC/math-to-emitc-failed.mlir new file mode 100644 index 0000000000000..f1de97c5465a9 --- /dev/null +++ b/mlir/test/Conversion/MathToEmitC/math-to-emitc-failed.mlir @@ -0,0 +1,23 @@ +// RUN: mlir-opt -split-input-file -convert-math-to-emitc -verify-diagnostics %s + +func.func @unsupported_tensor_type(%arg0 : tensor<4xf32>) -> tensor<4xf32> { +// expected-error @+1 {{failed to legalize operation 'math.absf' that was explicitly marked illegal}} + %0 = math.absf %arg0 : tensor<4xf32> + return %0 : tensor<4xf32> +} + +// ----- + +func.func @unsupported_f16_type(%arg0 : f16) -> f16 { +// expected-error @+1 {{failed to legalize operation 'math.absf' that was explicitly marked illegal}} + %0 = math.absf %arg0 : f16 + return %0 : f16 +} + +// ----- + +func.func @unsupported_f128_type(%arg0 : f128) -> f128 { +// expected-error @+1 {{failed to legalize operation 'math.absf' that was explicitly marked illegal}} + %0 = math.absf %arg0 : f128 + return %0 : f128 +} diff --git a/mlir/test/Conversion/MathToEmitC/math-to-emitc.mlir b/mlir/test/Conversion/MathToEmitC/math-to-emitc.mlir new file mode 100644 index 0000000000000..111d93de1accb --- /dev/null +++ b/mlir/test/Conversion/MathToEmitC/math-to-emitc.mlir @@ -0,0 +1,112 @@ +// RUN: mlir-opt -convert-math-to-emitc=language-target=c99 %s | FileCheck %s --check-prefix=c99 +// RUN: mlir-opt -convert-math-to-emitc=language-target=cpp11 %s | FileCheck %s --check-prefix=cpp11 + +func.func @absf(%arg0: f32, %arg1: f64) { + // c99: emitc.call_opaque "fabsf" + // c99-NEXT: emitc.call_opaque "fabs" + // cpp11: emitc.call_opaque "std::fabs" + // cpp11-NEXT: emitc.call_opaque "std::fabs" + %0 = math.absf %arg0 : f32 + %1 = math.absf %arg1 : f64 + return +} + +func.func @floor(%arg0: f32, %arg1: f64) { + // c99: emitc.call_opaque "floorf" + // c99-NEXT: emitc.call_opaque "floor" + // cpp11: emitc.call_opaque "std::floor" + // cpp11-NEXT: emitc.call_opaque "std::floor" + %0 = math.floor %arg0 : f32 + %1 = math.floor %arg1 : f64 + return +} + +func.func @sin(%arg0: f32, %arg1: f64) { + // c99: emitc.call_opaque "sinf" + // c99-NEXT: emitc.call_opaque "sin" + // cpp11: emitc.call_opaque "std::sin" + // cpp11-NEXT: emitc.call_opaque "std::sin" + %0 = math.sin %arg0 : f32 + %1 = math.sin %arg1 : f64 + return +} + +func.func @cos(%arg0: f32, %arg1: f64) { + // c99: emitc.call_opaque "cosf" + // c99-NEXT: emitc.call_opaque "cos" + // cpp11: emitc.call_opaque "std::cos" + // cpp11-NEXT: emitc.call_opaque "std::cos" + %0 = math.cos %arg0 : f32 + %1 = math.cos %arg1 : f64 + return +} + +func.func @asin(%arg0: f32, %arg1: f64) { + // c99: emitc.call_opaque "asinf" + // c99-NEXT: emitc.call_opaque "asin" + // cpp11: emitc.call_opaque "std::asin" + // cpp11-NEXT: emitc.call_opaque "std::asin" + %0 = math.asin %arg0 : f32 + %1 = math.asin %arg1 : f64 + return +} + +func.func @acos(%arg0: f32, %arg1: f64) { + // c99: emitc.call_opaque "acosf" + // c99-NEXT: emitc.call_opaque "acos" + // cpp11: emitc.call_opaque "std::acos" + // cpp11-NEXT: emitc.call_opaque "std::acos" + %0 = math.acos %arg0 : f32 + %1 = math.acos %arg1 : f64 + return +} + +func.func @atan2(%arg0: f32, %arg1: f32, %arg2: f64, %arg3: f64) { + // c99: emitc.call_opaque "atan2f" + // c99-NEXT: emitc.call_opaque "atan2" + // cpp11: emitc.call_opaque "std::atan2" + // cpp11-NEXT: emitc.call_opaque "std::atan2" + %0 = math.atan2 %arg0, %arg1 : f32 + %1 = math.atan2 %arg2, %arg3 : f64 + return +} + +func.func @ceil(%arg0: f32, %arg1: f64) { + // c99: emitc.call_opaque "ceilf" + // c99-NEXT: emitc.call_opaque "ceil" + // cpp11: emitc.call_opaque "std::ceil" + // cpp11-NEXT: emitc.call_opaque "std::ceil" + %0 = math.ceil %arg0 : f32 + %1 = math.ceil %arg1 : f64 + return +} + +func.func @exp(%arg0: f32, %arg1: f64) { + // c99: emitc.call_opaque "expf" + // c99-NEXT: emitc.call_opaque "exp" + // cpp11: emitc.call_opaque "std::exp" + // cpp11-NEXT: emitc.call_opaque "std::exp" + %0 = math.exp %arg0 : f32 + %1 = math.exp %arg1 : f64 + return +} + +func.func @powf(%arg0: f32, %arg1: f32, %arg2: f64, %arg3: f64) { + // c99: emitc.call_opaque "powf" + // c99-NEXT: emitc.call_opaque "pow" + // cpp11: emitc.call_opaque "std::pow" + // cpp11-NEXT: emitc.call_opaque "std::pow" + %0 = math.powf %arg0, %arg1 : f32 + %1 = math.powf %arg2, %arg3 : f64 + return +} + +func.func @round(%arg0: f32, %arg1: f64) { + // c99: emitc.call_opaque "roundf" + // c99-NEXT: emitc.call_opaque "round" + // cpp11: emitc.call_opaque "std::round" + // cpp11-NEXT: emitc.call_opaque "std::round" + %0 = math.round %arg0 : f32 + %1 = math.round %arg1 : f64 + return +} diff --git a/mlir/test/Dialect/LLVMIR/inlining-debuginfo.mlir b/mlir/test/Dialect/LLVMIR/inlining-debuginfo.mlir new file mode 100644 index 0000000000000..97a9f9f0a3d06 --- /dev/null +++ b/mlir/test/Dialect/LLVMIR/inlining-debuginfo.mlir @@ -0,0 +1,21 @@ +// RUN: mlir-opt %s -inline -mlir-print-debuginfo | FileCheck %s + +llvm.func @foo() -> !llvm.ptr + +llvm.func @with_byval_arg(%ptr : !llvm.ptr { llvm.byval = f64 }) { + llvm.return +} + +// CHECK-LABEL: llvm.func @test_byval +llvm.func @test_byval() { + // CHECK: %[[COPY:.+]] = llvm.alloca %{{.+}} x f64 + // CHECK-SAME: loc(#[[LOC:.+]]) + // CHECK: %[[ORIG:.+]] = llvm.call @foo() : () -> !llvm.ptr loc(#[[LOC]]) + %0 = llvm.call @foo() : () -> !llvm.ptr loc("inlining-debuginfo.mlir":14:2) + // CHECK: "llvm.intr.memcpy"(%[[COPY]], %[[ORIG]] + // CHECK-SAME: loc(#[[LOC]]) + llvm.call @with_byval_arg(%0) : (!llvm.ptr) -> () + llvm.return +} + +// CHECK: #[[LOC]] = loc("inlining-debuginfo.mlir":14:2) diff --git a/offload/cmake/caches/AMDGPUBot.cmake b/offload/cmake/caches/AMDGPUBot.cmake index 69bef91b2ce49..405abcc28f98d 100644 --- a/offload/cmake/caches/AMDGPUBot.cmake +++ b/offload/cmake/caches/AMDGPUBot.cmake @@ -5,6 +5,7 @@ set(CMAKE_INSTALL_PREFIX /tmp/llvm.install.test CACHE STRING "") # General settings set(CMAKE_BUILD_TYPE Release CACHE STRING "") +set(BUILD_SHARED_LIBS ON CACHE BOOL "") set(CMAKE_C_COMPILER_LAUNCHER ccache CACHE STRING "") set(CMAKE_CXX_COMPILER_LAUNCHER ccache CACHE STRING "") @@ -17,3 +18,4 @@ set(LLVM_TARGETS_TO_BUILD "host;AMDGPU" CACHE STRING "") set(LLVM_LIT_ARGS "-v --show-unsupported --timeout 100 --show-xfail -j 32" CACHE STRING "") set(CLANG_DEFAULT_LINKER "lld" CACHE STRING "") +set(CLANG_DEFAULT_RTLIB "compiler-rt" STRING "") diff --git a/polly/CMakeLists.txt b/polly/CMakeLists.txt index 955c171b3967f..c3232752d307c 100644 --- a/polly/CMakeLists.txt +++ b/polly/CMakeLists.txt @@ -112,6 +112,14 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) ) endif() +# add_llvm_pass_plugin() already declares the option, but we need access to +# it earlier than that. +set(link_into_tools_default OFF) +if (LLVM_TOOL_POLLY_BUILD) + set(link_into_tools_default ON) +endif() +option(LLVM_POLLY_LINK_INTO_TOOLS "Statically link Polly into tools (if available)" ${link_into_tools_default}) + add_definitions( -D_GNU_SOURCE ) add_subdirectory(docs) diff --git a/polly/cmake/polly_macros.cmake b/polly/cmake/polly_macros.cmake index ddd6376273376..9bd7b0b0ea591 100644 --- a/polly/cmake/polly_macros.cmake +++ b/polly/cmake/polly_macros.cmake @@ -39,15 +39,21 @@ macro(add_polly_library name) llvm_config(${name} ${LLVM_LINK_COMPONENTS}) endif( LLVM_LINK_COMPONENTS ) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "LLVMPolly") + set(exports) + if (LLVM_POLLY_LINK_INTO_TOOLS) + set(exports EXPORT LLVMExports) + endif() install(TARGETS ${name} COMPONENT ${name} - EXPORT LLVMExports + ${exports} LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) add_llvm_install_targets(install-${name} COMPONENT ${name}) endif() - set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name}) + if (LLVM_POLLY_LINK_INTO_TOOLS) + set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name}) + endif() endmacro(add_polly_library) macro(add_polly_loadable_module name) diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel index d3f3697903d72..1ec1c4bfad562 100644 --- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel @@ -2608,6 +2608,7 @@ td_library( ], includes = ["include"], deps = [ + ":BuiltinDialectTdFiles", ":InferTypeOpInterfaceTdFiles", ":OpBaseTdFiles", ":SideEffectInterfacesTdFiles", @@ -2618,11 +2619,17 @@ gentbl_cc_library( name = "IRDLIncGen", tbl_outs = [ ( - ["-gen-dialect-decls"], + [ + "-gen-dialect-decls", + "-dialect=irdl", + ], "include/mlir/Dialect/IRDL/IR/IRDLDialect.h.inc", ), ( - ["-gen-dialect-defs"], + [ + "-gen-dialect-defs", + "-dialect=irdl", + ], "include/mlir/Dialect/IRDL/IR/IRDLDialect.cpp.inc", ), ( @@ -4313,6 +4320,7 @@ cc_library( ":IndexToLLVM", ":IndexToSPIRV", ":LinalgToStandard", + ":MathToEmitC", ":MathToFuncs", ":MathToLLVM", ":MathToLibm", @@ -8901,6 +8909,27 @@ cc_library( ], ) +cc_library( + name = "MathToEmitC", + srcs = glob([ + "lib/Conversion/MathToEmitC/*.cpp", + ]), + hdrs = glob([ + "include/mlir/Conversion/MathToEmitC/*.h", + ]), + includes = [ + "include", + "lib/Conversion/MathToEmitC", + ], + deps = [ + ":ConversionPassIncGen", + ":EmitCDialect", + ":MathDialect", + ":Pass", + ":TransformUtils", + ], +) + cc_library( name = "MathToFuncs", srcs = glob(["lib/Conversion/MathToFuncs/*.cpp"]),