From 3d795bdd4d9067e96b2ff9e6278a5b8847eebe2b Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Thu, 11 Jan 2024 15:15:12 +0800 Subject: [PATCH 001/841] [InstCombine] Handle a bitreverse idiom which ends with a bswap (#77677) This patch handles the following `bitreverse` idiom, which is found in https://github.com/abseil/abseil-cpp/blob/8bd6445acc4bd0d123da2a44448b7218dfc70939/absl/crc/internal/crc.cc#L75-L80: ``` uint32_t ReverseBits(uint32_t bits) { bits = (bits & 0xaaaaaaaau) >> 1 | (bits & 0x55555555u) << 1; bits = (bits & 0xccccccccu) >> 2 | (bits & 0x33333333u) << 2; bits = (bits & 0xf0f0f0f0u) >> 4 | (bits & 0x0f0f0f0fu) << 4; return absl::gbswap_32(bits); } ``` Alive2: https://alive2.llvm.org/ce/z/ZYXNmj --- .../InstCombine/InstCombineCalls.cpp | 4 +++ llvm/lib/Transforms/Utils/Local.cpp | 3 ++- .../test/Transforms/InstCombine/bitreverse.ll | 26 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 40b48699f7585..64fbd5543a9e2 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1884,6 +1884,10 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { return crossLogicOpFold; } + // Try to fold into bitreverse if bswap is the root of the expression tree. + if (Instruction *BitOp = matchBSwapOrBitReverse(*II, /*MatchBSwaps*/ false, + /*MatchBitReversals*/ true)) + return BitOp; break; } case Intrinsic::masked_load: diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index c76cc9db16d7e..b9cad764aaef8 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -3905,7 +3905,8 @@ bool llvm::recognizeBSwapOrBitReverseIdiom( SmallVectorImpl &InsertedInsts) { if (!match(I, m_Or(m_Value(), m_Value())) && !match(I, m_FShl(m_Value(), m_Value(), m_Value())) && - !match(I, m_FShr(m_Value(), m_Value(), m_Value()))) + !match(I, m_FShr(m_Value(), m_Value(), m_Value())) && + !match(I, m_BSwap(m_Value()))) return false; if (!MatchBSwaps && !MatchBitReversals) return false; diff --git a/llvm/test/Transforms/InstCombine/bitreverse.ll b/llvm/test/Transforms/InstCombine/bitreverse.ll index 7d122297c11b2..cbe9695c48690 100644 --- a/llvm/test/Transforms/InstCombine/bitreverse.ll +++ b/llvm/test/Transforms/InstCombine/bitreverse.ll @@ -106,6 +106,30 @@ entry: ret i32 %or.4 } +define i32 @rev32_bswap(i32 %v) { +; CHECK-LABEL: @rev32_bswap( +; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[V:%.*]]) +; CHECK-NEXT: ret i32 [[RET]] +; + %and.i = lshr i32 %v, 1 + %shr.i = and i32 %and.i, 1431655765 + %and1.i = shl i32 %v, 1 + %shl.i = and i32 %and1.i, -1431655766 + %or.i = or disjoint i32 %shr.i, %shl.i + %and2.i = lshr i32 %or.i, 2 + %shr3.i = and i32 %and2.i, 858993459 + %and4.i = shl i32 %or.i, 2 + %shl5.i = and i32 %and4.i, -858993460 + %or6.i = or disjoint i32 %shr3.i, %shl5.i + %and7.i = lshr i32 %or6.i, 4 + %shr8.i = and i32 %and7.i, 252645135 + %and9.i = shl i32 %or6.i, 4 + %shl10.i = and i32 %and9.i, -252645136 + %or11.i = or disjoint i32 %shr8.i, %shl10.i + %ret = call i32 @llvm.bswap.i32(i32 %or11.i) + ret i32 %ret +} + define i64 @rev64(i64 %v) { ; CHECK-LABEL: @rev64( ; CHECK-NEXT: entry: @@ -508,3 +532,5 @@ define i64 @rev_all_operand64_multiuse_both(i64 %a, i64 %b) #0 { call void @use_i64(i64 %2) ret i64 %4 } + +declare i32 @llvm.bswap.i32(i32 %or11.i) From 211abe38d83aced510726601c7cf6b464f6ee5b1 Mon Sep 17 00:00:00 2001 From: Wang Pengcheng Date: Thu, 11 Jan 2024 15:28:12 +0800 Subject: [PATCH 002/841] [SelectionDAG] Add space-optimized forms of OPC_CheckComplexPat (#73310) We record the usage of each `ComplexPat` and sort the `ComplexPat`s by usage. For the top 8 `ComplexPat`s, we will emit a `OPC_CheckComplexPatN` to save one byte. Overall this reduces the llc binary size with all in-tree targets by about 89K. --- llvm/include/llvm/CodeGen/SelectionDAGISel.h | 8 +++ .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 14 ++++- llvm/test/TableGen/dag-isel-complexpattern.td | 2 +- llvm/utils/TableGen/DAGISelMatcherEmitter.cpp | 55 ++++++++++++++----- 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h index 40046e0a8dec9..99ce658e7eb71 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h @@ -207,6 +207,14 @@ class SelectionDAGISel : public MachineFunctionPass { OPC_CheckChild2CondCode, OPC_CheckValueType, OPC_CheckComplexPat, + OPC_CheckComplexPat0, + OPC_CheckComplexPat1, + OPC_CheckComplexPat2, + OPC_CheckComplexPat3, + OPC_CheckComplexPat4, + OPC_CheckComplexPat5, + OPC_CheckComplexPat6, + OPC_CheckComplexPat7, OPC_CheckAndImm, OPC_CheckOrImm, OPC_CheckImmAllOnesV, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 9acfc76d7d5ea..344dc8d8a9b67 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3358,8 +3358,18 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, break; continue; } - case OPC_CheckComplexPat: { - unsigned CPNum = MatcherTable[MatcherIndex++]; + case OPC_CheckComplexPat: + case OPC_CheckComplexPat0: + case OPC_CheckComplexPat1: + case OPC_CheckComplexPat2: + case OPC_CheckComplexPat3: + case OPC_CheckComplexPat4: + case OPC_CheckComplexPat5: + case OPC_CheckComplexPat6: + case OPC_CheckComplexPat7: { + unsigned CPNum = Opcode == OPC_CheckComplexPat + ? MatcherTable[MatcherIndex++] + : Opcode - OPC_CheckComplexPat0; unsigned RecNo = MatcherTable[MatcherIndex++]; assert(RecNo < RecordedNodes.size() && "Invalid CheckComplexPat"); diff --git a/llvm/test/TableGen/dag-isel-complexpattern.td b/llvm/test/TableGen/dag-isel-complexpattern.td index 3d74e4e46dc41..b8f517a1fc289 100644 --- a/llvm/test/TableGen/dag-isel-complexpattern.td +++ b/llvm/test/TableGen/dag-isel-complexpattern.td @@ -22,7 +22,7 @@ def CP32 : ComplexPattern; def INSTR : Instruction { // CHECK-LABEL: OPC_CheckOpcode, TARGET_VAL(ISD::STORE) // CHECK: OPC_CheckTypeI32 -// CHECK: OPC_CheckComplexPat, /*CP*/0, /*#*/1, // SelectCP32:$ +// CHECK: OPC_CheckComplexPat0, /*#*/1, // SelectCP32:$ // CHECK: Src: (st (add:{ *:[i32] } (CP32:{ *:[i32] }), (CP32:{ *:[i32] })), i64:{ *:[i64] }:$addr) let OutOperandList = (outs); let InOperandList = (ins GPR64:$addr); diff --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp index 6fd5698e7372e..e460a2804c664 100644 --- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -63,7 +63,6 @@ class MatcherTableEmitter { StringMap PatternPredicateMap; std::vector PatternPredicates; - DenseMap ComplexPatternMap; std::vector ComplexPatterns; @@ -84,8 +83,38 @@ class MatcherTableEmitter { } public: - MatcherTableEmitter(const CodeGenDAGPatterns &cgp) - : CGP(cgp), OpcodeCounts(Matcher::HighestKind + 1, 0) {} + MatcherTableEmitter(const Matcher *TheMatcher, const CodeGenDAGPatterns &cgp) + : CGP(cgp), OpcodeCounts(Matcher::HighestKind + 1, 0) { + // Record the usage of ComplexPattern. + DenseMap ComplexPatternUsage; + + // Iterate the whole MatcherTable once and do some statistics. + std::function Statistic = [&](const Matcher *N) { + while (N) { + if (auto *SM = dyn_cast(N)) + for (unsigned I = 0; I < SM->getNumChildren(); I++) + Statistic(SM->getChild(I)); + else if (auto *SOM = dyn_cast(N)) + for (unsigned I = 0; I < SOM->getNumCases(); I++) + Statistic(SOM->getCaseMatcher(I)); + else if (auto *STM = dyn_cast(N)) + for (unsigned I = 0; I < STM->getNumCases(); I++) + Statistic(STM->getCaseMatcher(I)); + else if (auto *CPM = dyn_cast(N)) + ++ComplexPatternUsage[&CPM->getPattern()]; + N = N->getNext(); + } + }; + Statistic(TheMatcher); + + // Sort ComplexPatterns by usage. + std::vector> ComplexPatternList( + ComplexPatternUsage.begin(), ComplexPatternUsage.end()); + sort(ComplexPatternList, + [](const auto &A, const auto &B) { return A.second > B.second; }); + for (const auto &ComplexPattern : ComplexPatternList) + ComplexPatterns.push_back(ComplexPattern.first); + } unsigned EmitMatcherList(const Matcher *N, const unsigned Indent, unsigned StartIdx, raw_ostream &OS); @@ -146,12 +175,7 @@ class MatcherTableEmitter { return Entry-1; } unsigned getComplexPat(const ComplexPattern &P) { - unsigned &Entry = ComplexPatternMap[&P]; - if (Entry == 0) { - ComplexPatterns.push_back(&P); - Entry = ComplexPatterns.size(); - } - return Entry-1; + return llvm::find(ComplexPatterns, &P) - ComplexPatterns.begin(); } unsigned getNodeXFormID(Record *Rec) { @@ -652,8 +676,13 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx, case Matcher::CheckComplexPat: { const CheckComplexPatMatcher *CCPM = cast(N); const ComplexPattern &Pattern = CCPM->getPattern(); - OS << "OPC_CheckComplexPat, /*CP*/" << getComplexPat(Pattern) << ", /*#*/" - << CCPM->getMatchNumber() << ','; + unsigned PatternNo = getComplexPat(Pattern); + if (PatternNo < 8) + OS << "OPC_CheckComplexPat" << PatternNo << ", /*#*/" + << CCPM->getMatchNumber() << ','; + else + OS << "OPC_CheckComplexPat, /*CP*/" << PatternNo << ", /*#*/" + << CCPM->getMatchNumber() << ','; if (!OmitComments) { OS << " // " << Pattern.getSelectFunc(); @@ -665,7 +694,7 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx, OS << " + chain result"; } OS << '\n'; - return 3; + return PatternNo < 8 ? 2 : 3; } case Matcher::CheckAndImm: { @@ -1267,7 +1296,7 @@ void llvm::EmitMatcherTable(Matcher *TheMatcher, OS << "#endif\n\n"; BeginEmitFunction(OS, "void", "SelectCode(SDNode *N)", false/*AddOverride*/); - MatcherTableEmitter MatcherEmitter(CGP); + MatcherTableEmitter MatcherEmitter(TheMatcher, CGP); // First we size all the children of the three kinds of matchers that have // them. This is done by sharing the code in EmitMatcher(). but we don't From 5c8d1238382ce3ef6004d9cbe3fe67b8342d868c Mon Sep 17 00:00:00 2001 From: Wang Pengcheng Date: Thu, 11 Jan 2024 15:36:21 +0800 Subject: [PATCH 003/841] [SelectionDAG] Add space-optimized forms of OPC_CheckPatternPredicate (#73319) We record the usage of each `PatternPredicate` and sort them by usage. For the top 8 `PatternPredicate`s, we will emit a `OPC_CheckPatternPredicateN` to save one byte. The old `OPC_CheckPatternPredicate2` is renamed to `OPC_CheckPatternPredicateTwoByte`. Overall this reduces the llc binary size with all in-tree targets by about 93K. --- llvm/include/llvm/CodeGen/SelectionDAGISel.h | 8 +++++ .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 34 ++++++++++++++----- llvm/utils/TableGen/DAGISelMatcherEmitter.cpp | 26 +++++++++----- 3 files changed, 51 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h index 99ce658e7eb71..e4d90f6e898fe 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h @@ -159,7 +159,15 @@ class SelectionDAGISel : public MachineFunctionPass { OPC_CheckChild2Same, OPC_CheckChild3Same, OPC_CheckPatternPredicate, + OPC_CheckPatternPredicate0, + OPC_CheckPatternPredicate1, OPC_CheckPatternPredicate2, + OPC_CheckPatternPredicate3, + OPC_CheckPatternPredicate4, + OPC_CheckPatternPredicate5, + OPC_CheckPatternPredicate6, + OPC_CheckPatternPredicate7, + OPC_CheckPatternPredicateTwoByte, OPC_CheckPredicate, OPC_CheckPredicateWithOperands, OPC_CheckOpcode, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 344dc8d8a9b67..678d273e4bd60 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2697,9 +2697,14 @@ LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckChildSame( /// CheckPatternPredicate - Implements OP_CheckPatternPredicate. LLVM_ATTRIBUTE_ALWAYS_INLINE static bool -CheckPatternPredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex, - const SelectionDAGISel &SDISel, bool TwoBytePredNo) { - unsigned PredNo = MatcherTable[MatcherIndex++]; +CheckPatternPredicate(unsigned Opcode, const unsigned char *MatcherTable, + unsigned &MatcherIndex, const SelectionDAGISel &SDISel) { + bool TwoBytePredNo = + Opcode == SelectionDAGISel::OPC_CheckPatternPredicateTwoByte; + unsigned PredNo = + TwoBytePredNo || Opcode == SelectionDAGISel::OPC_CheckPatternPredicate + ? MatcherTable[MatcherIndex++] + : Opcode - SelectionDAGISel::OPC_CheckPatternPredicate0; if (TwoBytePredNo) PredNo |= MatcherTable[MatcherIndex++] << 8; return SDISel.CheckPatternPredicate(PredNo); @@ -2851,10 +2856,16 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table, Table[Index-1] - SelectionDAGISel::OPC_CheckChild0Same); return Index; case SelectionDAGISel::OPC_CheckPatternPredicate: + case SelectionDAGISel::OPC_CheckPatternPredicate0: + case SelectionDAGISel::OPC_CheckPatternPredicate1: case SelectionDAGISel::OPC_CheckPatternPredicate2: - Result = !::CheckPatternPredicate( - Table, Index, SDISel, - Table[Index - 1] == SelectionDAGISel::OPC_CheckPatternPredicate2); + case SelectionDAGISel::OPC_CheckPatternPredicate3: + case SelectionDAGISel::OPC_CheckPatternPredicate4: + case SelectionDAGISel::OPC_CheckPatternPredicate5: + case SelectionDAGISel::OPC_CheckPatternPredicate6: + case SelectionDAGISel::OPC_CheckPatternPredicate7: + case SelectionDAGISel::OPC_CheckPatternPredicateTwoByte: + Result = !::CheckPatternPredicate(Opcode, Table, Index, SDISel); return Index; case SelectionDAGISel::OPC_CheckPredicate: Result = !::CheckNodePredicate(Table, Index, SDISel, N.getNode()); @@ -3336,9 +3347,16 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, continue; case OPC_CheckPatternPredicate: + case OPC_CheckPatternPredicate0: + case OPC_CheckPatternPredicate1: case OPC_CheckPatternPredicate2: - if (!::CheckPatternPredicate(MatcherTable, MatcherIndex, *this, - Opcode == OPC_CheckPatternPredicate2)) + case OPC_CheckPatternPredicate3: + case OPC_CheckPatternPredicate4: + case OPC_CheckPatternPredicate5: + case OPC_CheckPatternPredicate6: + case OPC_CheckPatternPredicate7: + case OPC_CheckPatternPredicateTwoByte: + if (!::CheckPatternPredicate(Opcode, MatcherTable, MatcherIndex, *this)) break; continue; case OPC_CheckPredicate: diff --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp index e460a2804c664..a3e2facf948e8 100644 --- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -60,7 +60,6 @@ class MatcherTableEmitter { // all the patterns with "identical" predicates. StringMap> NodePredicatesByCodeToRun; - StringMap PatternPredicateMap; std::vector PatternPredicates; std::vector ComplexPatterns; @@ -87,6 +86,8 @@ class MatcherTableEmitter { : CGP(cgp), OpcodeCounts(Matcher::HighestKind + 1, 0) { // Record the usage of ComplexPattern. DenseMap ComplexPatternUsage; + // Record the usage of PatternPredicate. + std::map PatternPredicateUsage; // Iterate the whole MatcherTable once and do some statistics. std::function Statistic = [&](const Matcher *N) { @@ -102,6 +103,8 @@ class MatcherTableEmitter { Statistic(STM->getCaseMatcher(I)); else if (auto *CPM = dyn_cast(N)) ++ComplexPatternUsage[&CPM->getPattern()]; + else if (auto *CPPM = dyn_cast(N)) + ++PatternPredicateUsage[CPPM->getPredicate()]; N = N->getNext(); } }; @@ -114,6 +117,14 @@ class MatcherTableEmitter { [](const auto &A, const auto &B) { return A.second > B.second; }); for (const auto &ComplexPattern : ComplexPatternList) ComplexPatterns.push_back(ComplexPattern.first); + + // Sort PatternPredicates by usage. + std::vector> PatternPredicateList( + PatternPredicateUsage.begin(), PatternPredicateUsage.end()); + sort(PatternPredicateList, + [](const auto &A, const auto &B) { return A.second > B.second; }); + for (const auto &PatternPredicate : PatternPredicateList) + PatternPredicates.push_back(PatternPredicate.first); } unsigned EmitMatcherList(const Matcher *N, const unsigned Indent, @@ -167,12 +178,7 @@ class MatcherTableEmitter { } unsigned getPatternPredicate(StringRef PredName) { - unsigned &Entry = PatternPredicateMap[PredName]; - if (Entry == 0) { - PatternPredicates.push_back(PredName.str()); - Entry = PatternPredicates.size(); - } - return Entry-1; + return llvm::find(PatternPredicates, PredName) - PatternPredicates.begin(); } unsigned getComplexPat(const ComplexPattern &P) { return llvm::find(ComplexPatterns, &P) - ComplexPatterns.begin(); @@ -510,13 +516,15 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx, StringRef Pred = cast(N)->getPredicate(); unsigned PredNo = getPatternPredicate(Pred); if (PredNo > 255) - OS << "OPC_CheckPatternPredicate2, TARGET_VAL(" << PredNo << "),"; + OS << "OPC_CheckPatternPredicateTwoByte, TARGET_VAL(" << PredNo << "),"; + else if (PredNo < 8) + OS << "OPC_CheckPatternPredicate" << PredNo << ','; else OS << "OPC_CheckPatternPredicate, " << PredNo << ','; if (!OmitComments) OS << " // " << Pred; OS << '\n'; - return 2 + (PredNo > 255); + return 2 + (PredNo > 255) - (PredNo < 8); } case Matcher::CheckPredicate: { TreePredicateFn Pred = cast(N)->getPredicate(); From 1a5792735aa0bb10e5624a438bcf7fd5091ee265 Mon Sep 17 00:00:00 2001 From: Wang Pengcheng Date: Thu, 11 Jan 2024 15:43:40 +0800 Subject: [PATCH 004/841] [SelectionDAG] Add space-optimized forms of OPC_CheckPredicate (#73488) We record the usage of each `Predicate` and sort them by usage. For the top 8 `Predicate`s, we will emit a `PC_CheckPredicateN` to save one byte. Overall this reduces the llc binary size with all in-tree targets by about 61K. --- llvm/include/llvm/CodeGen/SelectionDAGISel.h | 8 ++ .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 30 +++++- llvm/test/TableGen/address-space-patfrags.td | 4 +- llvm/test/TableGen/predicate-patfags.td | 4 +- llvm/utils/TableGen/DAGISelMatcherEmitter.cpp | 93 ++++++++++++------- 5 files changed, 94 insertions(+), 45 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h index e4d90f6e898fe..dbd9b391f4a43 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h @@ -169,6 +169,14 @@ class SelectionDAGISel : public MachineFunctionPass { OPC_CheckPatternPredicate7, OPC_CheckPatternPredicateTwoByte, OPC_CheckPredicate, + OPC_CheckPredicate0, + OPC_CheckPredicate1, + OPC_CheckPredicate2, + OPC_CheckPredicate3, + OPC_CheckPredicate4, + OPC_CheckPredicate5, + OPC_CheckPredicate6, + OPC_CheckPredicate7, OPC_CheckPredicateWithOperands, OPC_CheckOpcode, OPC_SwitchOpcode, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 678d273e4bd60..359d738d2ca09 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2712,9 +2712,13 @@ CheckPatternPredicate(unsigned Opcode, const unsigned char *MatcherTable, /// CheckNodePredicate - Implements OP_CheckNodePredicate. LLVM_ATTRIBUTE_ALWAYS_INLINE static bool -CheckNodePredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex, - const SelectionDAGISel &SDISel, SDNode *N) { - return SDISel.CheckNodePredicate(N, MatcherTable[MatcherIndex++]); +CheckNodePredicate(unsigned Opcode, const unsigned char *MatcherTable, + unsigned &MatcherIndex, const SelectionDAGISel &SDISel, + SDNode *N) { + unsigned PredNo = Opcode == SelectionDAGISel::OPC_CheckPredicate + ? MatcherTable[MatcherIndex++] + : Opcode - SelectionDAGISel::OPC_CheckPredicate0; + return SDISel.CheckNodePredicate(N, PredNo); } LLVM_ATTRIBUTE_ALWAYS_INLINE static bool @@ -2868,7 +2872,15 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table, Result = !::CheckPatternPredicate(Opcode, Table, Index, SDISel); return Index; case SelectionDAGISel::OPC_CheckPredicate: - Result = !::CheckNodePredicate(Table, Index, SDISel, N.getNode()); + case SelectionDAGISel::OPC_CheckPredicate0: + case SelectionDAGISel::OPC_CheckPredicate1: + case SelectionDAGISel::OPC_CheckPredicate2: + case SelectionDAGISel::OPC_CheckPredicate3: + case SelectionDAGISel::OPC_CheckPredicate4: + case SelectionDAGISel::OPC_CheckPredicate5: + case SelectionDAGISel::OPC_CheckPredicate6: + case SelectionDAGISel::OPC_CheckPredicate7: + Result = !::CheckNodePredicate(Opcode, Table, Index, SDISel, N.getNode()); return Index; case SelectionDAGISel::OPC_CheckOpcode: Result = !::CheckOpcode(Table, Index, N.getNode()); @@ -3359,8 +3371,16 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, if (!::CheckPatternPredicate(Opcode, MatcherTable, MatcherIndex, *this)) break; continue; + case SelectionDAGISel::OPC_CheckPredicate0: + case SelectionDAGISel::OPC_CheckPredicate1: + case SelectionDAGISel::OPC_CheckPredicate2: + case SelectionDAGISel::OPC_CheckPredicate3: + case SelectionDAGISel::OPC_CheckPredicate4: + case SelectionDAGISel::OPC_CheckPredicate5: + case SelectionDAGISel::OPC_CheckPredicate6: + case SelectionDAGISel::OPC_CheckPredicate7: case OPC_CheckPredicate: - if (!::CheckNodePredicate(MatcherTable, MatcherIndex, *this, + if (!::CheckNodePredicate(Opcode, MatcherTable, MatcherIndex, *this, N.getNode())) break; continue; diff --git a/llvm/test/TableGen/address-space-patfrags.td b/llvm/test/TableGen/address-space-patfrags.td index 27b174b4633cd..4aec6ea7e0eae 100644 --- a/llvm/test/TableGen/address-space-patfrags.td +++ b/llvm/test/TableGen/address-space-patfrags.td @@ -46,7 +46,7 @@ def inst_d : Instruction { let InOperandList = (ins GPR32:$src0, GPR32:$src1); } -// SDAG: case 2: { +// SDAG: case 1: { // SDAG-NEXT: // Predicate_pat_frag_b // SDAG-NEXT: // Predicate_truncstorei16_addrspace // SDAG-NEXT: SDNode *N = Node; @@ -69,7 +69,7 @@ def : Pat < >; -// SDAG: case 3: { +// SDAG: case 6: { // SDAG: // Predicate_pat_frag_a // SDAG-NEXT: SDNode *N = Node; // SDAG-NEXT: (void)N; diff --git a/llvm/test/TableGen/predicate-patfags.td b/llvm/test/TableGen/predicate-patfags.td index 0912b05127ef8..2cf29769dc13a 100644 --- a/llvm/test/TableGen/predicate-patfags.td +++ b/llvm/test/TableGen/predicate-patfags.td @@ -39,10 +39,10 @@ def TGTmul24_oneuse : PatFrag< } // SDAG: OPC_CheckOpcode, TARGET_VAL(ISD::INTRINSIC_W_CHAIN), -// SDAG: OPC_CheckPredicate, 0, // Predicate_TGTmul24_oneuse +// SDAG: OPC_CheckPredicate0, // Predicate_TGTmul24_oneuse // SDAG: OPC_CheckOpcode, TARGET_VAL(TargetISD::MUL24), -// SDAG: OPC_CheckPredicate, 0, // Predicate_TGTmul24_oneuse +// SDAG: OPC_CheckPredicate0, // Predicate_TGTmul24_oneuse // GISEL: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS), // GISEL: GIM_CheckIntrinsicID, /*MI*/1, /*Op*/1, GIMT_Encode2(Intrinsic::tgt_mul24), diff --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp index a3e2facf948e8..69d040f9b85c4 100644 --- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -52,9 +52,8 @@ class MatcherTableEmitter { SmallVector OpcodeCounts; - DenseMap NodePredicateMap; - std::vector NodePredicates; - std::vector NodePredicatesWithOperands; + std::vector NodePredicates; + std::vector NodePredicatesWithOperands; // We de-duplicate the predicates by code string, and use this map to track // all the patterns with "identical" predicates. @@ -88,6 +87,8 @@ class MatcherTableEmitter { DenseMap ComplexPatternUsage; // Record the usage of PatternPredicate. std::map PatternPredicateUsage; + // Record the usage of Predicate. + DenseMap PredicateUsage; // Iterate the whole MatcherTable once and do some statistics. std::function Statistic = [&](const Matcher *N) { @@ -105,6 +106,8 @@ class MatcherTableEmitter { ++ComplexPatternUsage[&CPM->getPattern()]; else if (auto *CPPM = dyn_cast(N)) ++PatternPredicateUsage[CPPM->getPredicate()]; + else if (auto *PM = dyn_cast(N)) + ++PredicateUsage[PM->getPredicate().getOrigPatFragRecord()]; N = N->getNext(); } }; @@ -125,6 +128,39 @@ class MatcherTableEmitter { [](const auto &A, const auto &B) { return A.second > B.second; }); for (const auto &PatternPredicate : PatternPredicateList) PatternPredicates.push_back(PatternPredicate.first); + + // Sort Predicates by usage. + // Merge predicates with same code. + for (const auto &Usage : PredicateUsage) { + TreePattern *TP = Usage.first; + TreePredicateFn Pred(TP); + NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()].push_back(TP); + } + + std::vector> PredicateList; + // Sum the usage. + for (auto &Predicate : NodePredicatesByCodeToRun) { + TinyPtrVector &TPs = Predicate.second; + sort(TPs, [](const auto *A, const auto *B) { + return A->getRecord()->getName() < B->getRecord()->getName(); + }); + unsigned Uses = 0; + for (TreePattern *TP : TPs) + Uses += PredicateUsage.at(TP); + + // We only add the first predicate here since they are with the same code. + PredicateList.push_back({TPs[0], Uses}); + } + + sort(PredicateList, + [](const auto &A, const auto &B) { return A.second > B.second; }); + for (const auto &Predicate : PredicateList) { + TreePattern *TP = Predicate.first; + if (TreePredicateFn(TP).usesOperands()) + NodePredicatesWithOperands.push_back(TP); + else + NodePredicates.push_back(TP); + } } unsigned EmitMatcherList(const Matcher *N, const unsigned Indent, @@ -139,7 +175,7 @@ class MatcherTableEmitter { void EmitPatternMatchTable(raw_ostream &OS); private: - void EmitNodePredicatesFunction(const std::vector &Preds, + void EmitNodePredicatesFunction(const std::vector &Preds, StringRef Decl, raw_ostream &OS); unsigned SizeMatcher(Matcher *N, raw_ostream &OS); @@ -148,33 +184,13 @@ class MatcherTableEmitter { raw_ostream &OS); unsigned getNodePredicate(TreePredicateFn Pred) { - TreePattern *TP = Pred.getOrigPatFragRecord(); - unsigned &Entry = NodePredicateMap[TP]; - if (Entry == 0) { - TinyPtrVector &SameCodePreds = - NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()]; - if (SameCodePreds.empty()) { - // We've never seen a predicate with the same code: allocate an entry. - if (Pred.usesOperands()) { - NodePredicatesWithOperands.push_back(Pred); - Entry = NodePredicatesWithOperands.size(); - } else { - NodePredicates.push_back(Pred); - Entry = NodePredicates.size(); - } - } else { - // We did see an identical predicate: re-use it. - Entry = NodePredicateMap[SameCodePreds.front()]; - assert(Entry != 0); - assert(TreePredicateFn(SameCodePreds.front()).usesOperands() == - Pred.usesOperands() && - "PatFrags with some code must have same usesOperands setting"); - } - // In both cases, we've never seen this particular predicate before, so - // mark it in the list of predicates sharing the same code. - SameCodePreds.push_back(TP); - } - return Entry-1; + // We use the first predicate. + TreePattern *PredPat = + NodePredicatesByCodeToRun[Pred.getCodeToRunOnSDNode()][0]; + return Pred.usesOperands() + ? llvm::find(NodePredicatesWithOperands, PredPat) - + NodePredicatesWithOperands.begin() + : llvm::find(NodePredicates, PredPat) - NodePredicates.begin(); } unsigned getPatternPredicate(StringRef PredName) { @@ -529,6 +545,7 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx, case Matcher::CheckPredicate: { TreePredicateFn Pred = cast(N)->getPredicate(); unsigned OperandBytes = 0; + unsigned PredNo = getNodePredicate(Pred); if (Pred.usesOperands()) { unsigned NumOps = cast(N)->getNumOperands(); @@ -537,10 +554,15 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx, OS << cast(N)->getOperandNo(i) << ", "; OperandBytes = 1 + NumOps; } else { - OS << "OPC_CheckPredicate, "; + if (PredNo < 8) { + OperandBytes = -1; + OS << "OPC_CheckPredicate" << PredNo << ", "; + } else + OS << "OPC_CheckPredicate, "; } - OS << getNodePredicate(Pred) << ','; + if (PredNo >= 8 || Pred.usesOperands()) + OS << PredNo << ','; if (!OmitComments) OS << " // " << Pred.getFnName(); OS << '\n'; @@ -1029,8 +1051,7 @@ EmitMatcherList(const Matcher *N, const unsigned Indent, unsigned CurrentIdx, } void MatcherTableEmitter::EmitNodePredicatesFunction( - const std::vector &Preds, StringRef Decl, - raw_ostream &OS) { + const std::vector &Preds, StringRef Decl, raw_ostream &OS) { if (Preds.empty()) return; @@ -1040,7 +1061,7 @@ void MatcherTableEmitter::EmitNodePredicatesFunction( OS << " default: llvm_unreachable(\"Invalid predicate in table?\");\n"; for (unsigned i = 0, e = Preds.size(); i != e; ++i) { // Emit the predicate code corresponding to this pattern. - const TreePredicateFn PredFn = Preds[i]; + TreePredicateFn PredFn(Preds[i]); assert(!PredFn.isAlwaysTrue() && "No code in this predicate"); std::string PredFnCodeStr = PredFn.getCodeToRunOnSDNode(); From 3643d11988d6b14171b4320cbdfb15aba9764d0b Mon Sep 17 00:00:00 2001 From: jeanPerier Date: Thu, 11 Jan 2024 08:50:35 +0100 Subject: [PATCH 005/841] [flang][hlfir] Support box in user defined assignments (#77578) When dealing with overlaps in user defined assignments, some entities with descriptors (fir.box) may be saved without descriptors. The current code was replacing the original box entity with the "raw" copy with a simple cast instead of creating a box for the copy. This patch ensures a fir.embox is emitted instead. --- .../LowerHLFIROrderedAssignments.cpp | 8 +++++++ .../user-defined-assignment.fir | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp index c4aee7d39e4a3..84101353a740a 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp @@ -421,6 +421,14 @@ convertToMoldType(mlir::Location loc, fir::FirOpBuilder &builder, } // Variable to Variable mismatch (e.g., fir.heap vs fir.ref), or value // to Value mismatch (e.g. i1 vs fir.logical<4>). + if (mlir::isa(mold.getType()) && + !mlir::isa(input.getType())) { + // An entity may have have been saved without descriptor while the original + // value had a descriptor (e.g., it was not contiguous). + auto emboxed = hlfir::convertToBox(loc, builder, input, mold.getType()); + assert(!emboxed.second && "temp should already be in memory"); + input = hlfir::Entity{fir::getBase(emboxed.first)}; + } return hlfir::Entity{builder.createConvert(loc, mold.getType(), input)}; } diff --git a/flang/test/HLFIR/order_assignments/user-defined-assignment.fir b/flang/test/HLFIR/order_assignments/user-defined-assignment.fir index 521288d0cfa12..61836b8bcc57e 100644 --- a/flang/test/HLFIR/order_assignments/user-defined-assignment.fir +++ b/flang/test/HLFIR/order_assignments/user-defined-assignment.fir @@ -180,3 +180,26 @@ func.func @test_scalar_forall_overlap(%i: !fir.ref>) { // CHECK: fir.call @logical_value_to_numeric(%[[VAL_32]], %[[VAL_33]]) : (!fir.ref, !fir.logical<4>) -> () // CHECK: } // CHECK: fir.freemem %[[VAL_15]] : !fir.heap> + +func.func @test_saved_scalar_box(%arg0: !fir.box>, %arg1: !fir.class>) { + hlfir.region_assign { + hlfir.yield %arg0 : !fir.box> + } to { + hlfir.yield %arg1 : !fir.class> + } user_defined_assign (%arg2: !fir.box>) to (%arg3: !fir.class>) { + fir.call @user_assign_box(%arg3, %arg2) : (!fir.class>, !fir.box>) -> () + } + return +} +func.func private @user_assign_box(!fir.class>, !fir.box>) -> () + +// CHECK-LABEL: func.func @test_saved_scalar_box( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.class>) { +// CHECK: %[[VAL_2:.*]] = hlfir.as_expr %[[VAL_0]] : (!fir.box>) -> !hlfir.expr> +// CHECK: %[[VAL_3:.*]]:3 = hlfir.associate %[[VAL_2]] +// CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1 : (!fir.ref>) -> !fir.box> +// CHECK: fir.call @user_assign_box(%[[VAL_1]], %[[VAL_4]]) : (!fir.class>, !fir.box>) -> () +// CHECK: hlfir.end_associate %[[VAL_3]]#1, %[[VAL_3]]#2 : !fir.ref>, i1 +// CHECK: return +// CHECK: } From e3993e044ec5925e59c131f798f823a9f16f0433 Mon Sep 17 00:00:00 2001 From: Timm Baeder Date: Thu, 11 Jan 2024 09:02:24 +0100 Subject: [PATCH 006/841] [clang][Interp] Implement __builtin_addressof (#77303) We don't need to do anything here, since the input is already a Pointer. The only complexity is that we pre-classify the parameters as PT_Ptr, but they might end up being of a different pointer type, e.g. PT_FnPtr. --- clang/lib/AST/Interp/Interp.cpp | 12 ++++++++++ clang/lib/AST/Interp/InterpBuiltin.cpp | 33 +++++++++++++++++++++++--- clang/test/AST/Interp/functions.cpp | 24 +++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 21ea2503b94bf..9de0926b9dba9 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -134,6 +134,18 @@ void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC) { if (CurFunc->isUnevaluatedBuiltin()) return; + // Some builtin functions require us to only look at the call site, since + // the classified parameter types do not match. + if (CurFunc->isBuiltin()) { + const auto *CE = + cast(S.Current->Caller->getExpr(S.Current->getRetPC())); + for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) { + const Expr *A = CE->getArg(I); + popArg(S, A); + } + return; + } + if (S.Current->Caller && CurFunc->isVariadic()) { // CallExpr we're look for is at the return PC of the current function, i.e. // in the caller. diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index b55b1569a2598..754ca96b0c645 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -164,6 +164,8 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result, case X: \ return Ret(S, OpPC, Result); switch (*T) { + RET_CASE(PT_Ptr); + RET_CASE(PT_FnPtr); RET_CASE(PT_Float); RET_CASE(PT_Bool); RET_CASE(PT_Sint8); @@ -613,15 +615,34 @@ static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, + const Function *Func, + const CallExpr *Call) { + PrimType PtrT = + S.getContext().classify(Call->getArg(0)->getType()).value_or(PT_Ptr); + + if (PtrT == PT_FnPtr) { + const FunctionPointer &Arg = S.Stk.peek(); + S.Stk.push(Arg); + } else if (PtrT == PT_Ptr) { + const Pointer &Arg = S.Stk.peek(); + S.Stk.push(Arg); + } else { + assert(false && "Unsupported pointer type passed to __builtin_addressof()"); + } + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; APValue Dummy; - QualType ReturnType = Call->getCallReturnType(S.getCtx()); - std::optional ReturnT = S.getContext().classify(ReturnType); + std::optional ReturnT = S.getContext().classify(Call->getType()); + // If classify failed, we assume void. - assert(ReturnT || ReturnType->isVoidType()); + assert(ReturnT || Call->getType()->isVoidType()); switch (F->getBuiltinID()) { case Builtin::BI__builtin_is_constant_evaluated: @@ -820,6 +841,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, if (!interp__builtin_ffs(S, OpPC, Frame, F, Call)) return false; break; + case Builtin::BIaddressof: + case Builtin::BI__addressof: + case Builtin::BI__builtin_addressof: + if (!interp__builtin_addressof(S, OpPC, Frame, F, Call)) + return false; + break; default: return false; diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 179a195098b13..75f3c5d192b2c 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -389,3 +389,27 @@ namespace Packs { static_assert(foo() == 2, ""); static_assert(foo<>() == 0, ""); } + +namespace AddressOf { + struct S {} s; + static_assert(__builtin_addressof(s) == &s, ""); + + struct T { constexpr T *operator&() const { return nullptr; } int n; } t; + constexpr T *pt = __builtin_addressof(t); + static_assert(&pt->n == &t.n, ""); + + struct U { int n : 5; } u; + int *pbf = __builtin_addressof(u.n); // expected-error {{address of bit-field requested}} \ + // ref-error {{address of bit-field requested}} + + S *ptmp = __builtin_addressof(S{}); // expected-error {{taking the address of a temporary}} \ + // expected-warning {{temporary whose address is used as value of local variable 'ptmp' will be destroyed at the end of the full-expression}} \ + // ref-error {{taking the address of a temporary}} \ + // ref-warning {{temporary whose address is used as value of local variable 'ptmp' will be destroyed at the end of the full-expression}} + + constexpr int foo() {return 1;} + static_assert(__builtin_addressof(foo) == foo, ""); + + constexpr _Complex float F = {3, 4}; + static_assert(__builtin_addressof(F) == &F, ""); +} From 79889fedc57707e99740abc1f48e6c5601d5a3f3 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Thu, 11 Jan 2024 15:07:24 +0700 Subject: [PATCH 007/841] [RISCV] Deduplicate version struct in RISCVISAInfo. NFC (#77645) We have two structs for representing the version of an extension in RISCVISAInfo, RISCVExtensionInfo and RISCVExtensionVersion, both with the exact same fields. This patch deduplicates them. --- clang/lib/Basic/Targets/RISCV.cpp | 5 +- lld/ELF/Arch/RISCV.cpp | 4 +- llvm/include/llvm/Support/RISCVISAInfo.h | 16 +- llvm/lib/Support/RISCVISAInfo.cpp | 331 ++++++++++---------- llvm/unittests/Support/RISCVISAInfoTest.cpp | 86 ++--- 5 files changed, 221 insertions(+), 221 deletions(-) diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index daaa8639ae835..fb312b6cf26e0 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -163,9 +163,8 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, auto ExtName = Extension.first; auto ExtInfo = Extension.second; - Builder.defineMacro( - Twine("__riscv_", ExtName), - Twine(getVersionValue(ExtInfo.MajorVersion, ExtInfo.MinorVersion))); + Builder.defineMacro(Twine("__riscv_", ExtName), + Twine(getVersionValue(ExtInfo.Major, ExtInfo.Minor))); } if (ISAInfo->hasExtension("m") || ISAInfo->hasExtension("zmmul")) diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index 62498ded1a2b1..8906de0737354 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -957,8 +957,8 @@ static void mergeArch(RISCVISAInfo::OrderedExtensionMap &mergedExts, } else { for (const auto &ext : info.getExtensions()) { if (auto it = mergedExts.find(ext.first); it != mergedExts.end()) { - if (std::tie(it->second.MajorVersion, it->second.MinorVersion) >= - std::tie(ext.second.MajorVersion, ext.second.MinorVersion)) + if (std::tie(it->second.Major, it->second.Minor) >= + std::tie(ext.second.Major, ext.second.Minor)) continue; } mergedExts[ext.first] = ext.second; diff --git a/llvm/include/llvm/Support/RISCVISAInfo.h b/llvm/include/llvm/Support/RISCVISAInfo.h index 97f1051b0540a..46df93d752260 100644 --- a/llvm/include/llvm/Support/RISCVISAInfo.h +++ b/llvm/include/llvm/Support/RISCVISAInfo.h @@ -18,11 +18,6 @@ #include namespace llvm { -struct RISCVExtensionInfo { - unsigned MajorVersion; - unsigned MinorVersion; -}; - void riscvExtensionsHelp(StringMap DescMap); class RISCVISAInfo { @@ -30,6 +25,12 @@ class RISCVISAInfo { RISCVISAInfo(const RISCVISAInfo &) = delete; RISCVISAInfo &operator=(const RISCVISAInfo &) = delete; + /// Represents the major and version number components of a RISC-V extension. + struct ExtensionVersion { + unsigned Major; + unsigned Minor; + }; + static bool compareExtension(const std::string &LHS, const std::string &RHS); /// Helper class for OrderedExtensionMap. @@ -41,7 +42,7 @@ class RISCVISAInfo { /// OrderedExtensionMap is std::map, it's specialized to keep entries /// in canonical order of extension. - typedef std::map + typedef std::map OrderedExtensionMap; RISCVISAInfo(unsigned XLen, OrderedExtensionMap &Exts) @@ -104,8 +105,7 @@ class RISCVISAInfo { OrderedExtensionMap Exts; - void addExtension(StringRef ExtName, unsigned MajorVersion, - unsigned MinorVersion); + void addExtension(StringRef ExtName, ExtensionVersion Version); Error checkDependency(); diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index 70f531e40b90e..390d950486a79 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -24,16 +24,11 @@ using namespace llvm; namespace { -/// Represents the major and version number components of a RISC-V extension -struct RISCVExtensionVersion { - unsigned Major; - unsigned Minor; -}; struct RISCVSupportedExtension { const char *Name; /// Supported version. - RISCVExtensionVersion Version; + RISCVISAInfo::ExtensionVersion Version; bool operator<(const RISCVSupportedExtension &RHS) const { return StringRef(Name) < StringRef(RHS.Name); @@ -50,161 +45,161 @@ static const char *RISCVGImplications[] = { // NOTE: This table should be sorted alphabetically by extension name. static const RISCVSupportedExtension SupportedExtensions[] = { - {"a", RISCVExtensionVersion{2, 1}}, - {"c", RISCVExtensionVersion{2, 0}}, - {"d", RISCVExtensionVersion{2, 2}}, - {"e", RISCVExtensionVersion{2, 0}}, - {"f", RISCVExtensionVersion{2, 2}}, - {"h", RISCVExtensionVersion{1, 0}}, - {"i", RISCVExtensionVersion{2, 1}}, - {"m", RISCVExtensionVersion{2, 0}}, - - {"smaia", RISCVExtensionVersion{1, 0}}, - {"ssaia", RISCVExtensionVersion{1, 0}}, - {"svinval", RISCVExtensionVersion{1, 0}}, - {"svnapot", RISCVExtensionVersion{1, 0}}, - {"svpbmt", RISCVExtensionVersion{1, 0}}, - - {"v", RISCVExtensionVersion{1, 0}}, + {"a", {2, 1}}, + {"c", {2, 0}}, + {"d", {2, 2}}, + {"e", {2, 0}}, + {"f", {2, 2}}, + {"h", {1, 0}}, + {"i", {2, 1}}, + {"m", {2, 0}}, + + {"smaia", {1, 0}}, + {"ssaia", {1, 0}}, + {"svinval", {1, 0}}, + {"svnapot", {1, 0}}, + {"svpbmt", {1, 0}}, + + {"v", {1, 0}}, // vendor-defined ('X') extensions - {"xcvalu", RISCVExtensionVersion{1, 0}}, - {"xcvbi", RISCVExtensionVersion{1, 0}}, - {"xcvbitmanip", RISCVExtensionVersion{1, 0}}, - {"xcvelw", RISCVExtensionVersion{1, 0}}, - {"xcvmac", RISCVExtensionVersion{1, 0}}, - {"xcvmem", RISCVExtensionVersion{1, 0}}, - {"xcvsimd", RISCVExtensionVersion{1, 0}}, - {"xsfvcp", RISCVExtensionVersion{1, 0}}, - {"xsfvfnrclipxfqf", RISCVExtensionVersion{1, 0}}, - {"xsfvfwmaccqqq", RISCVExtensionVersion{1, 0}}, - {"xsfvqmaccdod", RISCVExtensionVersion{1, 0}}, - {"xsfvqmaccqoq", RISCVExtensionVersion{1, 0}}, - {"xtheadba", RISCVExtensionVersion{1, 0}}, - {"xtheadbb", RISCVExtensionVersion{1, 0}}, - {"xtheadbs", RISCVExtensionVersion{1, 0}}, - {"xtheadcmo", RISCVExtensionVersion{1, 0}}, - {"xtheadcondmov", RISCVExtensionVersion{1, 0}}, - {"xtheadfmemidx", RISCVExtensionVersion{1, 0}}, - {"xtheadmac", RISCVExtensionVersion{1, 0}}, - {"xtheadmemidx", RISCVExtensionVersion{1, 0}}, - {"xtheadmempair", RISCVExtensionVersion{1, 0}}, - {"xtheadsync", RISCVExtensionVersion{1, 0}}, - {"xtheadvdot", RISCVExtensionVersion{1, 0}}, - {"xventanacondops", RISCVExtensionVersion{1, 0}}, - - {"zawrs", RISCVExtensionVersion{1, 0}}, - - {"zba", RISCVExtensionVersion{1, 0}}, - {"zbb", RISCVExtensionVersion{1, 0}}, - {"zbc", RISCVExtensionVersion{1, 0}}, - {"zbkb", RISCVExtensionVersion{1, 0}}, - {"zbkc", RISCVExtensionVersion{1, 0}}, - {"zbkx", RISCVExtensionVersion{1, 0}}, - {"zbs", RISCVExtensionVersion{1, 0}}, - - {"zca", RISCVExtensionVersion{1, 0}}, - {"zcb", RISCVExtensionVersion{1, 0}}, - {"zcd", RISCVExtensionVersion{1, 0}}, - {"zce", RISCVExtensionVersion{1, 0}}, - {"zcf", RISCVExtensionVersion{1, 0}}, - {"zcmp", RISCVExtensionVersion{1, 0}}, - {"zcmt", RISCVExtensionVersion{1, 0}}, - - {"zdinx", RISCVExtensionVersion{1, 0}}, - - {"zfa", RISCVExtensionVersion{1, 0}}, - {"zfh", RISCVExtensionVersion{1, 0}}, - {"zfhmin", RISCVExtensionVersion{1, 0}}, - {"zfinx", RISCVExtensionVersion{1, 0}}, - - {"zhinx", RISCVExtensionVersion{1, 0}}, - {"zhinxmin", RISCVExtensionVersion{1, 0}}, - - {"zicbom", RISCVExtensionVersion{1, 0}}, - {"zicbop", RISCVExtensionVersion{1, 0}}, - {"zicboz", RISCVExtensionVersion{1, 0}}, - {"zicntr", RISCVExtensionVersion{2, 0}}, - {"zicsr", RISCVExtensionVersion{2, 0}}, - {"zifencei", RISCVExtensionVersion{2, 0}}, - {"zihintntl", RISCVExtensionVersion{1, 0}}, - {"zihintpause", RISCVExtensionVersion{2, 0}}, - {"zihpm", RISCVExtensionVersion{2, 0}}, - - {"zk", RISCVExtensionVersion{1, 0}}, - {"zkn", RISCVExtensionVersion{1, 0}}, - {"zknd", RISCVExtensionVersion{1, 0}}, - {"zkne", RISCVExtensionVersion{1, 0}}, - {"zknh", RISCVExtensionVersion{1, 0}}, - {"zkr", RISCVExtensionVersion{1, 0}}, - {"zks", RISCVExtensionVersion{1, 0}}, - {"zksed", RISCVExtensionVersion{1, 0}}, - {"zksh", RISCVExtensionVersion{1, 0}}, - {"zkt", RISCVExtensionVersion{1, 0}}, - - {"zmmul", RISCVExtensionVersion{1, 0}}, - - {"zvbb", RISCVExtensionVersion{1, 0}}, - {"zvbc", RISCVExtensionVersion{1, 0}}, - - {"zve32f", RISCVExtensionVersion{1, 0}}, - {"zve32x", RISCVExtensionVersion{1, 0}}, - {"zve64d", RISCVExtensionVersion{1, 0}}, - {"zve64f", RISCVExtensionVersion{1, 0}}, - {"zve64x", RISCVExtensionVersion{1, 0}}, - - {"zvfh", RISCVExtensionVersion{1, 0}}, - {"zvfhmin", RISCVExtensionVersion{1, 0}}, + {"xcvalu", {1, 0}}, + {"xcvbi", {1, 0}}, + {"xcvbitmanip", {1, 0}}, + {"xcvelw", {1, 0}}, + {"xcvmac", {1, 0}}, + {"xcvmem", {1, 0}}, + {"xcvsimd", {1, 0}}, + {"xsfvcp", {1, 0}}, + {"xsfvfnrclipxfqf", {1, 0}}, + {"xsfvfwmaccqqq", {1, 0}}, + {"xsfvqmaccdod", {1, 0}}, + {"xsfvqmaccqoq", {1, 0}}, + {"xtheadba", {1, 0}}, + {"xtheadbb", {1, 0}}, + {"xtheadbs", {1, 0}}, + {"xtheadcmo", {1, 0}}, + {"xtheadcondmov", {1, 0}}, + {"xtheadfmemidx", {1, 0}}, + {"xtheadmac", {1, 0}}, + {"xtheadmemidx", {1, 0}}, + {"xtheadmempair", {1, 0}}, + {"xtheadsync", {1, 0}}, + {"xtheadvdot", {1, 0}}, + {"xventanacondops", {1, 0}}, + + {"zawrs", {1, 0}}, + + {"zba", {1, 0}}, + {"zbb", {1, 0}}, + {"zbc", {1, 0}}, + {"zbkb", {1, 0}}, + {"zbkc", {1, 0}}, + {"zbkx", {1, 0}}, + {"zbs", {1, 0}}, + + {"zca", {1, 0}}, + {"zcb", {1, 0}}, + {"zcd", {1, 0}}, + {"zce", {1, 0}}, + {"zcf", {1, 0}}, + {"zcmp", {1, 0}}, + {"zcmt", {1, 0}}, + + {"zdinx", {1, 0}}, + + {"zfa", {1, 0}}, + {"zfh", {1, 0}}, + {"zfhmin", {1, 0}}, + {"zfinx", {1, 0}}, + + {"zhinx", {1, 0}}, + {"zhinxmin", {1, 0}}, + + {"zicbom", {1, 0}}, + {"zicbop", {1, 0}}, + {"zicboz", {1, 0}}, + {"zicntr", {2, 0}}, + {"zicsr", {2, 0}}, + {"zifencei", {2, 0}}, + {"zihintntl", {1, 0}}, + {"zihintpause", {2, 0}}, + {"zihpm", {2, 0}}, + + {"zk", {1, 0}}, + {"zkn", {1, 0}}, + {"zknd", {1, 0}}, + {"zkne", {1, 0}}, + {"zknh", {1, 0}}, + {"zkr", {1, 0}}, + {"zks", {1, 0}}, + {"zksed", {1, 0}}, + {"zksh", {1, 0}}, + {"zkt", {1, 0}}, + + {"zmmul", {1, 0}}, + + {"zvbb", {1, 0}}, + {"zvbc", {1, 0}}, + + {"zve32f", {1, 0}}, + {"zve32x", {1, 0}}, + {"zve64d", {1, 0}}, + {"zve64f", {1, 0}}, + {"zve64x", {1, 0}}, + + {"zvfh", {1, 0}}, + {"zvfhmin", {1, 0}}, // vector crypto - {"zvkb", RISCVExtensionVersion{1, 0}}, - {"zvkg", RISCVExtensionVersion{1, 0}}, - {"zvkn", RISCVExtensionVersion{1, 0}}, - {"zvknc", RISCVExtensionVersion{1, 0}}, - {"zvkned", RISCVExtensionVersion{1, 0}}, - {"zvkng", RISCVExtensionVersion{1, 0}}, - {"zvknha", RISCVExtensionVersion{1, 0}}, - {"zvknhb", RISCVExtensionVersion{1, 0}}, - {"zvks", RISCVExtensionVersion{1, 0}}, - {"zvksc", RISCVExtensionVersion{1, 0}}, - {"zvksed", RISCVExtensionVersion{1, 0}}, - {"zvksg", RISCVExtensionVersion{1, 0}}, - {"zvksh", RISCVExtensionVersion{1, 0}}, - {"zvkt", RISCVExtensionVersion{1, 0}}, - - {"zvl1024b", RISCVExtensionVersion{1, 0}}, - {"zvl128b", RISCVExtensionVersion{1, 0}}, - {"zvl16384b", RISCVExtensionVersion{1, 0}}, - {"zvl2048b", RISCVExtensionVersion{1, 0}}, - {"zvl256b", RISCVExtensionVersion{1, 0}}, - {"zvl32768b", RISCVExtensionVersion{1, 0}}, - {"zvl32b", RISCVExtensionVersion{1, 0}}, - {"zvl4096b", RISCVExtensionVersion{1, 0}}, - {"zvl512b", RISCVExtensionVersion{1, 0}}, - {"zvl64b", RISCVExtensionVersion{1, 0}}, - {"zvl65536b", RISCVExtensionVersion{1, 0}}, - {"zvl8192b", RISCVExtensionVersion{1, 0}}, + {"zvkb", {1, 0}}, + {"zvkg", {1, 0}}, + {"zvkn", {1, 0}}, + {"zvknc", {1, 0}}, + {"zvkned", {1, 0}}, + {"zvkng", {1, 0}}, + {"zvknha", {1, 0}}, + {"zvknhb", {1, 0}}, + {"zvks", {1, 0}}, + {"zvksc", {1, 0}}, + {"zvksed", {1, 0}}, + {"zvksg", {1, 0}}, + {"zvksh", {1, 0}}, + {"zvkt", {1, 0}}, + + {"zvl1024b", {1, 0}}, + {"zvl128b", {1, 0}}, + {"zvl16384b", {1, 0}}, + {"zvl2048b", {1, 0}}, + {"zvl256b", {1, 0}}, + {"zvl32768b", {1, 0}}, + {"zvl32b", {1, 0}}, + {"zvl4096b", {1, 0}}, + {"zvl512b", {1, 0}}, + {"zvl64b", {1, 0}}, + {"zvl65536b", {1, 0}}, + {"zvl8192b", {1, 0}}, }; // NOTE: This table should be sorted alphabetically by extension name. static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { - {"zacas", RISCVExtensionVersion{1, 0}}, + {"zacas", {1, 0}}, - {"zcmop", RISCVExtensionVersion{0, 2}}, + {"zcmop", {0, 2}}, - {"zfbfmin", RISCVExtensionVersion{0, 8}}, + {"zfbfmin", {0, 8}}, - {"zicfilp", RISCVExtensionVersion{0, 4}}, - {"zicfiss", RISCVExtensionVersion{0, 4}}, + {"zicfilp", {0, 4}}, + {"zicfiss", {0, 4}}, - {"zicond", RISCVExtensionVersion{1, 0}}, + {"zicond", {1, 0}}, - {"zimop", RISCVExtensionVersion{0, 1}}, + {"zimop", {0, 1}}, - {"ztso", RISCVExtensionVersion{0, 1}}, + {"ztso", {0, 1}}, - {"zvfbfmin", RISCVExtensionVersion{0, 8}}, - {"zvfbfwma", RISCVExtensionVersion{0, 8}}, + {"zvfbfmin", {0, 8}}, + {"zvfbfwma", {0, 8}}, }; static void verifyTables() { @@ -237,8 +232,8 @@ void llvm::riscvExtensionsHelp(StringMap DescMap) { for (const auto &E : SupportedExtensions) ExtMap[E.Name] = {E.Version.Major, E.Version.Minor}; for (const auto &E : ExtMap) { - std::string Version = std::to_string(E.second.MajorVersion) + "." + - std::to_string(E.second.MinorVersion); + std::string Version = + std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor); PrintExtension(E.first, Version, DescMap[E.first]); } @@ -247,8 +242,8 @@ void llvm::riscvExtensionsHelp(StringMap DescMap) { for (const auto &E : SupportedExperimentalExtensions) ExtMap[E.Name] = {E.Version.Major, E.Version.Minor}; for (const auto &E : ExtMap) { - std::string Version = std::to_string(E.second.MajorVersion) + "." + - std::to_string(E.second.MinorVersion); + std::string Version = + std::to_string(E.second.Major) + "." + std::to_string(E.second.Minor); PrintExtension(E.first, Version, DescMap["experimental-" + E.first]); } @@ -293,7 +288,7 @@ struct LessExtName { }; } // namespace -static std::optional +static std::optional findDefaultVersion(StringRef ExtName) { // Find default version of an extension. // TODO: We might set default version based on profile or ISA spec. @@ -309,12 +304,9 @@ findDefaultVersion(StringRef ExtName) { return std::nullopt; } -void RISCVISAInfo::addExtension(StringRef ExtName, unsigned MajorVersion, - unsigned MinorVersion) { - RISCVExtensionInfo Ext; - Ext.MajorVersion = MajorVersion; - Ext.MinorVersion = MinorVersion; - Exts[ExtName.str()] = Ext; +void RISCVISAInfo::addExtension(StringRef ExtName, + RISCVISAInfo::ExtensionVersion Version) { + Exts[ExtName.str()] = Version; } static StringRef getExtensionTypeDesc(StringRef Ext) { @@ -337,7 +329,7 @@ static StringRef getExtensionType(StringRef Ext) { return StringRef(); } -static std::optional +static std::optional isExperimentalExtension(StringRef Ext) { auto I = llvm::lower_bound(SupportedExperimentalExtensions, Ext, LessExtName()); @@ -634,8 +626,7 @@ RISCVISAInfo::parseFeatures(unsigned XLen, continue; if (Add) - ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version.Major, - ExtensionInfoIterator->Version.Minor); + ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version); else ISAInfo->Exts.erase(ExtName.str()); } @@ -696,7 +687,7 @@ RISCVISAInfo::parseNormalizedArchString(StringRef Arch) { if (MajorVersionStr.getAsInteger(10, MajorVersion)) return createStringError(errc::invalid_argument, "failed to parse major version number"); - ISAInfo->addExtension(ExtName, MajorVersion, MinorVersion); + ISAInfo->addExtension(ExtName, {MajorVersion, MinorVersion}); } ISAInfo->updateFLen(); ISAInfo->updateMinVLen(); @@ -775,7 +766,7 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension, // ISA spec. for (const auto *Ext : RISCVGImplications) { if (auto Version = findDefaultVersion(Ext)) - ISAInfo->addExtension(Ext, Version->Major, Version->Minor); + ISAInfo->addExtension(Ext, *Version); else llvm_unreachable("Default extension version not found?"); } @@ -794,7 +785,7 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension, Minor = Version->Minor; } - ISAInfo->addExtension(StringRef(&Baseline, 1), Major, Minor); + ISAInfo->addExtension(StringRef(&Baseline, 1), {Major, Minor}); } // Consume the base ISA version number and any '_' between rvxxx and the @@ -860,7 +851,7 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension, "unsupported standard user-level extension '%c'", C); } - ISAInfo->addExtension(StringRef(&C, 1), Major, Minor); + ISAInfo->addExtension(StringRef(&C, 1), {Major, Minor}); // Consume full extension name and version, including any optional '_' // between this extension and the next @@ -928,7 +919,7 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension, if (IgnoreUnknown && !isSupportedExtension(Name)) continue; - ISAInfo->addExtension(Name, Major, Minor); + ISAInfo->addExtension(Name, {Major, Minor}); // Extension format is correct, keep parsing the extensions. // TODO: Save Type, Name, Major, Minor to avoid parsing them later. AllExts.push_back(Name); @@ -1143,7 +1134,7 @@ void RISCVISAInfo::updateImplication() { // implied if (!HasE && !HasI) { auto Version = findDefaultVersion("i"); - addExtension("i", Version->Major, Version->Minor); + addExtension("i", Version.value()); } assert(llvm::is_sorted(ImpliedExts) && "Table not sorted by Name"); @@ -1164,7 +1155,7 @@ void RISCVISAInfo::updateImplication() { if (Exts.count(ImpliedExt)) continue; auto Version = findDefaultVersion(ImpliedExt); - addExtension(ImpliedExt, Version->Major, Version->Minor); + addExtension(ImpliedExt, Version.value()); WorkList.insert(ImpliedExt); } } @@ -1174,7 +1165,7 @@ void RISCVISAInfo::updateImplication() { if (XLen == 32 && Exts.count("zce") && Exts.count("f") && !Exts.count("zcf")) { auto Version = findDefaultVersion("zcf"); - addExtension("zcf", Version->Major, Version->Minor); + addExtension("zcf", Version.value()); } } @@ -1209,7 +1200,7 @@ void RISCVISAInfo::updateCombination() { IsAllRequiredFeatureExist &= hasExtension(Ext); if (IsAllRequiredFeatureExist) { auto Version = findDefaultVersion(CombineExt); - addExtension(CombineExt, Version->Major, Version->Minor); + addExtension(CombineExt, Version.value()); IsNewCombine = true; } } @@ -1266,7 +1257,7 @@ std::string RISCVISAInfo::toString() const { StringRef ExtName = Ext.first; auto ExtInfo = Ext.second; Arch << LS << ExtName; - Arch << ExtInfo.MajorVersion << "p" << ExtInfo.MinorVersion; + Arch << ExtInfo.Major << "p" << ExtInfo.Minor; } return Arch.str(); diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp index 42759f30fd1bc..997551e5c44c0 100644 --- a/llvm/unittests/Support/RISCVISAInfoTest.cpp +++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp @@ -15,9 +15,9 @@ using ::testing::ElementsAre; using namespace llvm; -bool operator==(const llvm::RISCVExtensionInfo &A, - const llvm::RISCVExtensionInfo &B) { - return A.MajorVersion == B.MajorVersion && A.MinorVersion == B.MinorVersion; +bool operator==(const RISCVISAInfo::ExtensionVersion &A, + const RISCVISAInfo::ExtensionVersion &B) { + return A.Major == B.Major && A.Minor == B.Minor; } TEST(ParseNormalizedArchString, RejectsUpperCase) { @@ -50,28 +50,32 @@ TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) { ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded()); RISCVISAInfo &InfoRV32I = **MaybeRV32I; EXPECT_EQ(InfoRV32I.getExtensions().size(), 1UL); - EXPECT_TRUE(InfoRV32I.getExtensions().at("i") == (RISCVExtensionInfo{2, 0})); + EXPECT_TRUE(InfoRV32I.getExtensions().at("i") == + (RISCVISAInfo::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV32I.getXLen(), 32U); auto MaybeRV32E = RISCVISAInfo::parseNormalizedArchString("rv32e2p0"); ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded()); RISCVISAInfo &InfoRV32E = **MaybeRV32E; EXPECT_EQ(InfoRV32E.getExtensions().size(), 1UL); - EXPECT_TRUE(InfoRV32E.getExtensions().at("e") == (RISCVExtensionInfo{2, 0})); + EXPECT_TRUE(InfoRV32E.getExtensions().at("e") == + (RISCVISAInfo::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV32E.getXLen(), 32U); auto MaybeRV64I = RISCVISAInfo::parseNormalizedArchString("rv64i2p0"); ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded()); RISCVISAInfo &InfoRV64I = **MaybeRV64I; EXPECT_EQ(InfoRV64I.getExtensions().size(), 1UL); - EXPECT_TRUE(InfoRV64I.getExtensions().at("i") == (RISCVExtensionInfo{2, 0})); + EXPECT_TRUE(InfoRV64I.getExtensions().at("i") == + (RISCVISAInfo::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV64I.getXLen(), 64U); auto MaybeRV64E = RISCVISAInfo::parseNormalizedArchString("rv64e2p0"); ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded()); RISCVISAInfo &InfoRV64E = **MaybeRV64E; EXPECT_EQ(InfoRV64E.getExtensions().size(), 1UL); - EXPECT_TRUE(InfoRV64E.getExtensions().at("e") == (RISCVExtensionInfo{2, 0})); + EXPECT_TRUE(InfoRV64E.getExtensions().at("e") == + (RISCVISAInfo::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV64E.getXLen(), 64U); } @@ -81,12 +85,16 @@ TEST(ParseNormalizedArchString, AcceptsArbitraryExtensionsAndVersions) { ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); RISCVISAInfo &Info = **MaybeISAInfo; EXPECT_EQ(Info.getExtensions().size(), 5UL); - EXPECT_TRUE(Info.getExtensions().at("i") == (RISCVExtensionInfo{5, 1})); - EXPECT_TRUE(Info.getExtensions().at("m") == (RISCVExtensionInfo{3, 2})); + EXPECT_TRUE(Info.getExtensions().at("i") == + (RISCVISAInfo::ExtensionVersion{5, 1})); + EXPECT_TRUE(Info.getExtensions().at("m") == + (RISCVISAInfo::ExtensionVersion{3, 2})); EXPECT_TRUE(Info.getExtensions().at("zmadeup") == - (RISCVExtensionInfo{11, 12})); - EXPECT_TRUE(Info.getExtensions().at("sfoo") == (RISCVExtensionInfo{2, 0})); - EXPECT_TRUE(Info.getExtensions().at("xbar") == (RISCVExtensionInfo{3, 0})); + (RISCVISAInfo::ExtensionVersion{11, 12})); + EXPECT_TRUE(Info.getExtensions().at("sfoo") == + (RISCVISAInfo::ExtensionVersion{2, 0})); + EXPECT_TRUE(Info.getExtensions().at("xbar") == + (RISCVISAInfo::ExtensionVersion{3, 0})); } TEST(ParseNormalizedArchString, UpdatesFLenMinVLenMaxELen) { @@ -131,7 +139,7 @@ TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) { RISCVISAInfo &InfoRV32I = **MaybeRV32I; RISCVISAInfo::OrderedExtensionMap ExtsRV32I = InfoRV32I.getExtensions(); EXPECT_EQ(ExtsRV32I.size(), 1UL); - EXPECT_TRUE(ExtsRV32I.at("i") == (RISCVExtensionInfo{2, 1})); + EXPECT_TRUE(ExtsRV32I.at("i") == (RISCVISAInfo::ExtensionVersion{2, 1})); EXPECT_EQ(InfoRV32I.getXLen(), 32U); EXPECT_EQ(InfoRV32I.getFLen(), 0U); @@ -140,7 +148,7 @@ TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) { RISCVISAInfo &InfoRV32E = **MaybeRV32E; RISCVISAInfo::OrderedExtensionMap ExtsRV32E = InfoRV32E.getExtensions(); EXPECT_EQ(ExtsRV32E.size(), 1UL); - EXPECT_TRUE(ExtsRV32E.at("e") == (RISCVExtensionInfo{2, 0})); + EXPECT_TRUE(ExtsRV32E.at("e") == (RISCVISAInfo::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV32E.getXLen(), 32U); EXPECT_EQ(InfoRV32E.getFLen(), 0U); @@ -149,13 +157,14 @@ TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) { RISCVISAInfo &InfoRV32G = **MaybeRV32G; RISCVISAInfo::OrderedExtensionMap ExtsRV32G = InfoRV32G.getExtensions(); EXPECT_EQ(ExtsRV32G.size(), 7UL); - EXPECT_TRUE(ExtsRV32G.at("i") == (RISCVExtensionInfo{2, 1})); - EXPECT_TRUE(ExtsRV32G.at("m") == (RISCVExtensionInfo{2, 0})); - EXPECT_TRUE(ExtsRV32G.at("a") == (RISCVExtensionInfo{2, 1})); - EXPECT_TRUE(ExtsRV32G.at("f") == (RISCVExtensionInfo{2, 2})); - EXPECT_TRUE(ExtsRV32G.at("d") == (RISCVExtensionInfo{2, 2})); - EXPECT_TRUE(ExtsRV32G.at("zicsr") == (RISCVExtensionInfo{2, 0})); - EXPECT_TRUE(ExtsRV32G.at("zifencei") == (RISCVExtensionInfo{2, 0})); + EXPECT_TRUE(ExtsRV32G.at("i") == (RISCVISAInfo::ExtensionVersion{2, 1})); + EXPECT_TRUE(ExtsRV32G.at("m") == (RISCVISAInfo::ExtensionVersion{2, 0})); + EXPECT_TRUE(ExtsRV32G.at("a") == (RISCVISAInfo::ExtensionVersion{2, 1})); + EXPECT_TRUE(ExtsRV32G.at("f") == (RISCVISAInfo::ExtensionVersion{2, 2})); + EXPECT_TRUE(ExtsRV32G.at("d") == (RISCVISAInfo::ExtensionVersion{2, 2})); + EXPECT_TRUE(ExtsRV32G.at("zicsr") == (RISCVISAInfo::ExtensionVersion{2, 0})); + EXPECT_TRUE(ExtsRV32G.at("zifencei") == + (RISCVISAInfo::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV32G.getXLen(), 32U); EXPECT_EQ(InfoRV32G.getFLen(), 64U); @@ -164,7 +173,7 @@ TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) { RISCVISAInfo &InfoRV64I = **MaybeRV64I; RISCVISAInfo::OrderedExtensionMap ExtsRV64I = InfoRV64I.getExtensions(); EXPECT_EQ(ExtsRV64I.size(), 1UL); - EXPECT_TRUE(ExtsRV64I.at("i") == (RISCVExtensionInfo{2, 1})); + EXPECT_TRUE(ExtsRV64I.at("i") == (RISCVISAInfo::ExtensionVersion{2, 1})); EXPECT_EQ(InfoRV64I.getXLen(), 64U); EXPECT_EQ(InfoRV64I.getFLen(), 0U); @@ -173,7 +182,7 @@ TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) { RISCVISAInfo &InfoRV64E = **MaybeRV64E; RISCVISAInfo::OrderedExtensionMap ExtsRV64E = InfoRV64E.getExtensions(); EXPECT_EQ(ExtsRV64E.size(), 1UL); - EXPECT_TRUE(ExtsRV64E.at("e") == (RISCVExtensionInfo{2, 0})); + EXPECT_TRUE(ExtsRV64E.at("e") == (RISCVISAInfo::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV64E.getXLen(), 64U); EXPECT_EQ(InfoRV64E.getFLen(), 0U); @@ -182,13 +191,14 @@ TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) { RISCVISAInfo &InfoRV64G = **MaybeRV64G; RISCVISAInfo::OrderedExtensionMap ExtsRV64G = InfoRV64G.getExtensions(); EXPECT_EQ(ExtsRV64G.size(), 7UL); - EXPECT_TRUE(ExtsRV64G.at("i") == (RISCVExtensionInfo{2, 1})); - EXPECT_TRUE(ExtsRV64G.at("m") == (RISCVExtensionInfo{2, 0})); - EXPECT_TRUE(ExtsRV64G.at("a") == (RISCVExtensionInfo{2, 1})); - EXPECT_TRUE(ExtsRV64G.at("f") == (RISCVExtensionInfo{2, 2})); - EXPECT_TRUE(ExtsRV64G.at("d") == (RISCVExtensionInfo{2, 2})); - EXPECT_TRUE(ExtsRV64G.at("zicsr") == (RISCVExtensionInfo{2, 0})); - EXPECT_TRUE(ExtsRV64G.at("zifencei") == (RISCVExtensionInfo{2, 0})); + EXPECT_TRUE(ExtsRV64G.at("i") == (RISCVISAInfo::ExtensionVersion{2, 1})); + EXPECT_TRUE(ExtsRV64G.at("m") == (RISCVISAInfo::ExtensionVersion{2, 0})); + EXPECT_TRUE(ExtsRV64G.at("a") == (RISCVISAInfo::ExtensionVersion{2, 1})); + EXPECT_TRUE(ExtsRV64G.at("f") == (RISCVISAInfo::ExtensionVersion{2, 2})); + EXPECT_TRUE(ExtsRV64G.at("d") == (RISCVISAInfo::ExtensionVersion{2, 2})); + EXPECT_TRUE(ExtsRV64G.at("zicsr") == (RISCVISAInfo::ExtensionVersion{2, 0})); + EXPECT_TRUE(ExtsRV64G.at("zifencei") == + (RISCVISAInfo::ExtensionVersion{2, 0})); EXPECT_EQ(InfoRV64G.getXLen(), 64U); EXPECT_EQ(InfoRV64G.getFLen(), 64U); } @@ -236,7 +246,7 @@ TEST(ParseArchString, IgnoresUnrecognizedExtensionNamesWithIgnoreUnknown) { RISCVISAInfo &Info = **MaybeISAInfo; RISCVISAInfo::OrderedExtensionMap Exts = Info.getExtensions(); EXPECT_EQ(Exts.size(), 1UL); - EXPECT_TRUE(Exts.at("i") == (RISCVExtensionInfo{2, 1})); + EXPECT_TRUE(Exts.at("i") == (RISCVISAInfo::ExtensionVersion{2, 1})); } // Checks that supported extensions aren't incorrectly ignored when a @@ -245,7 +255,7 @@ TEST(ParseArchString, IgnoresUnrecognizedExtensionNamesWithIgnoreUnknown) { RISCVISAInfo::parseArchString("rv32i_zbc1p0_xmadeup", true, false, true); ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); - EXPECT_TRUE(Exts.at("zbc") == (RISCVExtensionInfo{1, 0})); + EXPECT_TRUE(Exts.at("zbc") == (RISCVISAInfo::ExtensionVersion{1, 0})); } TEST(ParseArchString, AcceptsVersionInLongOrShortForm) { @@ -253,13 +263,13 @@ TEST(ParseArchString, AcceptsVersionInLongOrShortForm) { auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); - EXPECT_TRUE(Exts.at("i") == (RISCVExtensionInfo{2, 1})); + EXPECT_TRUE(Exts.at("i") == (RISCVISAInfo::ExtensionVersion{2, 1})); } for (StringRef Input : {"rv32i_zfinx1", "rv32i_zfinx1p0"}) { auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); - EXPECT_TRUE(Exts.at("zfinx") == (RISCVExtensionInfo{1, 0})); + EXPECT_TRUE(Exts.at("zfinx") == (RISCVISAInfo::ExtensionVersion{1, 0})); } } @@ -288,14 +298,14 @@ TEST(ParseArchString, ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); EXPECT_EQ(Exts.size(), 1UL); - EXPECT_TRUE(Exts.at("i") == (RISCVExtensionInfo{2, 1})); + EXPECT_TRUE(Exts.at("i") == (RISCVISAInfo::ExtensionVersion{2, 1})); } for (StringRef Input : {"rv32e0p1", "rv32e99p99", "rv64e0p1", "rv64e99p99"}) { auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true, false, true); ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); EXPECT_EQ(Exts.size(), 1UL); - EXPECT_TRUE(Exts.at("e") == (RISCVExtensionInfo{2, 0})); + EXPECT_TRUE(Exts.at("e") == (RISCVISAInfo::ExtensionVersion{2, 0})); } } @@ -306,7 +316,7 @@ TEST(ParseArchString, ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); EXPECT_EQ(Exts.size(), 1UL); - EXPECT_TRUE(Exts.at("i") == (RISCVExtensionInfo{2, 1})); + EXPECT_TRUE(Exts.at("i") == (RISCVISAInfo::ExtensionVersion{2, 1})); } } @@ -396,7 +406,7 @@ TEST(ParseArchString, ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); RISCVISAInfo::OrderedExtensionMap Exts = (*MaybeISAInfo)->getExtensions(); EXPECT_EQ(Exts.size(), 2UL); - EXPECT_TRUE(Exts.at("zicond") == (RISCVExtensionInfo{9, 9})); + EXPECT_TRUE(Exts.at("zicond") == (RISCVISAInfo::ExtensionVersion{9, 9})); } TEST(ParseArchString, RejectsUnrecognizedVersionForExperimentalExtension) { From 16945bc16dbb4c4acac854001b73e1454f3b601c Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Thu, 11 Jan 2024 09:14:52 +0100 Subject: [PATCH 008/841] [AMDGPU] Don't send DEALLOC_VGPRs after calls (#77439) Calls do not have to wait for VsCnt, so after they return there might still be scratch stores in progress. It's important that we don't send the DEALLOC_VGPR message in that case, since that might release the VGPRs and scratch allocation before those stores are complete. --- llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp | 5 +-- .../CodeGen/AMDGPU/call-argument-types.ll | 2 -- .../CodeGen/AMDGPU/calling-conventions.ll | 4 --- .../AMDGPU/global_atomics_scan_fadd.ll | 24 -------------- .../AMDGPU/promote-constOffset-to-imm.ll | 16 ---------- llvm/test/CodeGen/AMDGPU/release-vgprs.mir | 32 +++++++++++++++++++ 6 files changed, 35 insertions(+), 48 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp index 1cb1d32707f2d..1f480c248154e 100644 --- a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp +++ b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp @@ -292,7 +292,7 @@ class WaitcntBrackets { VgprVmemTypes[GprNo] = 0; } - void setNonKernelFunctionInitialState() { + void setStateOnFunctionEntryOrReturn() { setScoreUB(VS_CNT, getWaitCountMax(VS_CNT)); PendingEvents |= WaitEventMaskForInst[VS_CNT]; } @@ -1487,6 +1487,7 @@ void SIInsertWaitcnts::updateEventWaitcntAfter(MachineInstr &Inst, if (callWaitsOnFunctionReturn(Inst)) { // Act as a wait on everything ScoreBrackets->applyWaitcnt(AMDGPU::Waitcnt::allZeroExceptVsCnt()); + ScoreBrackets->setStateOnFunctionEntryOrReturn(); } else { // May need to way wait for anything. ScoreBrackets->applyWaitcnt(AMDGPU::Waitcnt()); @@ -1879,7 +1880,7 @@ bool SIInsertWaitcnts::runOnMachineFunction(MachineFunction &MF) { auto NonKernelInitialState = std::make_unique(ST, Limits, Encoding); - NonKernelInitialState->setNonKernelFunctionInitialState(); + NonKernelInitialState->setStateOnFunctionEntryOrReturn(); BlockInfos[&EntryBB].Incoming = std::move(NonKernelInitialState); Modified = true; diff --git a/llvm/test/CodeGen/AMDGPU/call-argument-types.ll b/llvm/test/CodeGen/AMDGPU/call-argument-types.ll index a192a1b8dff93..87e17a1c82080 100644 --- a/llvm/test/CodeGen/AMDGPU/call-argument-types.ll +++ b/llvm/test/CodeGen/AMDGPU/call-argument-types.ll @@ -4462,8 +4462,6 @@ define amdgpu_kernel void @test_call_external_i32_func_i32_imm(ptr addrspace(1) ; GFX11-NEXT: s_swappc_b64 s[30:31], s[0:1] ; GFX11-NEXT: buffer_store_b32 v0, off, s[36:39], 0 dlc ; GFX11-NEXT: s_waitcnt_vscnt null, 0x0 -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm ; ; HSA-LABEL: test_call_external_i32_func_i32_imm: diff --git a/llvm/test/CodeGen/AMDGPU/calling-conventions.ll b/llvm/test/CodeGen/AMDGPU/calling-conventions.ll index d63ebdeb50a1f..ce1ce649c227d 100644 --- a/llvm/test/CodeGen/AMDGPU/calling-conventions.ll +++ b/llvm/test/CodeGen/AMDGPU/calling-conventions.ll @@ -167,8 +167,6 @@ define amdgpu_kernel void @call_coldcc() #0 { ; GFX11-NEXT: s_waitcnt lgkmcnt(0) ; GFX11-NEXT: s_swappc_b64 s[30:31], s[0:1] ; GFX11-NEXT: global_store_b32 v[0:1], v0, off -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm %val = call float @coldcc(float 1.0) store float %val, ptr addrspace(1) undef @@ -231,8 +229,6 @@ define amdgpu_kernel void @call_fastcc() #0 { ; GFX11-NEXT: s_waitcnt lgkmcnt(0) ; GFX11-NEXT: s_swappc_b64 s[30:31], s[0:1] ; GFX11-NEXT: global_store_b32 v[0:1], v0, off -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm %val = call float @fastcc(float 1.0) store float %val, ptr addrspace(1) undef diff --git a/llvm/test/CodeGen/AMDGPU/global_atomics_scan_fadd.ll b/llvm/test/CodeGen/AMDGPU/global_atomics_scan_fadd.ll index 5ebd3eef69f25..499046a2e222d 100644 --- a/llvm/test/CodeGen/AMDGPU/global_atomics_scan_fadd.ll +++ b/llvm/test/CodeGen/AMDGPU/global_atomics_scan_fadd.ll @@ -626,8 +626,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1164-NEXT: s_waitcnt lgkmcnt(0) ; GFX1164-NEXT: global_atomic_add_f32 v0, v1, s[0:1] ; GFX1164-NEXT: .LBB1_4: -; GFX1164-NEXT: s_nop 0 -; GFX1164-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1164-NEXT: s_endpgm ; ; GFX1132-LABEL: global_atomic_fadd_uni_address_div_value_agent_scope_align4_unsafe: @@ -675,8 +673,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1132-NEXT: s_waitcnt lgkmcnt(0) ; GFX1132-NEXT: global_atomic_add_f32 v0, v1, s[0:1] ; GFX1132-NEXT: .LBB1_4: -; GFX1132-NEXT: s_nop 0 -; GFX1132-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1132-NEXT: s_endpgm ; ; GFX9-DPP-LABEL: global_atomic_fadd_uni_address_div_value_agent_scope_align4_unsafe: @@ -988,8 +984,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1164-DPP-NEXT: s_waitcnt lgkmcnt(0) ; GFX1164-DPP-NEXT: global_atomic_add_f32 v4, v0, s[0:1] ; GFX1164-DPP-NEXT: .LBB1_2: -; GFX1164-DPP-NEXT: s_nop 0 -; GFX1164-DPP-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1164-DPP-NEXT: s_endpgm ; ; GFX1132-DPP-LABEL: global_atomic_fadd_uni_address_div_value_agent_scope_align4_unsafe: @@ -1051,8 +1045,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1132-DPP-NEXT: s_waitcnt lgkmcnt(0) ; GFX1132-DPP-NEXT: global_atomic_add_f32 v4, v0, s[0:1] ; GFX1132-DPP-NEXT: .LBB1_2: -; GFX1132-DPP-NEXT: s_nop 0 -; GFX1132-DPP-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1132-DPP-NEXT: s_endpgm %divValue = call float @div.float.value() %result = atomicrmw fadd ptr addrspace(1) %ptr, float %divValue syncscope("agent") monotonic, align 4 @@ -3042,8 +3034,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1164-NEXT: s_waitcnt lgkmcnt(0) ; GFX1164-NEXT: global_atomic_add_f32 v0, v1, s[0:1] ; GFX1164-NEXT: .LBB5_4: -; GFX1164-NEXT: s_nop 0 -; GFX1164-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1164-NEXT: s_endpgm ; ; GFX1132-LABEL: global_atomic_fadd_uni_address_div_value_agent_scope_unsafe: @@ -3091,8 +3081,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1132-NEXT: s_waitcnt lgkmcnt(0) ; GFX1132-NEXT: global_atomic_add_f32 v0, v1, s[0:1] ; GFX1132-NEXT: .LBB5_4: -; GFX1132-NEXT: s_nop 0 -; GFX1132-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1132-NEXT: s_endpgm ; ; GFX9-DPP-LABEL: global_atomic_fadd_uni_address_div_value_agent_scope_unsafe: @@ -3404,8 +3392,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1164-DPP-NEXT: s_waitcnt lgkmcnt(0) ; GFX1164-DPP-NEXT: global_atomic_add_f32 v4, v0, s[0:1] ; GFX1164-DPP-NEXT: .LBB5_2: -; GFX1164-DPP-NEXT: s_nop 0 -; GFX1164-DPP-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1164-DPP-NEXT: s_endpgm ; ; GFX1132-DPP-LABEL: global_atomic_fadd_uni_address_div_value_agent_scope_unsafe: @@ -3467,8 +3453,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1132-DPP-NEXT: s_waitcnt lgkmcnt(0) ; GFX1132-DPP-NEXT: global_atomic_add_f32 v4, v0, s[0:1] ; GFX1132-DPP-NEXT: .LBB5_2: -; GFX1132-DPP-NEXT: s_nop 0 -; GFX1132-DPP-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1132-DPP-NEXT: s_endpgm %divValue = call float @div.float.value() %result = atomicrmw fadd ptr addrspace(1) %ptr, float %divValue syncscope("agent") monotonic @@ -3770,8 +3754,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1164-NEXT: s_waitcnt lgkmcnt(0) ; GFX1164-NEXT: global_atomic_add_f32 v0, v1, s[0:1] ; GFX1164-NEXT: .LBB6_4: -; GFX1164-NEXT: s_nop 0 -; GFX1164-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1164-NEXT: s_endpgm ; ; GFX1132-LABEL: global_atomic_fadd_uni_address_div_value_agent_scope_unsafe_structfp: @@ -3819,8 +3801,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1132-NEXT: s_waitcnt lgkmcnt(0) ; GFX1132-NEXT: global_atomic_add_f32 v0, v1, s[0:1] ; GFX1132-NEXT: .LBB6_4: -; GFX1132-NEXT: s_nop 0 -; GFX1132-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1132-NEXT: s_endpgm ; ; GFX9-DPP-LABEL: global_atomic_fadd_uni_address_div_value_agent_scope_unsafe_structfp: @@ -4132,8 +4112,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1164-DPP-NEXT: s_waitcnt lgkmcnt(0) ; GFX1164-DPP-NEXT: global_atomic_add_f32 v4, v0, s[0:1] ; GFX1164-DPP-NEXT: .LBB6_2: -; GFX1164-DPP-NEXT: s_nop 0 -; GFX1164-DPP-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1164-DPP-NEXT: s_endpgm ; ; GFX1132-DPP-LABEL: global_atomic_fadd_uni_address_div_value_agent_scope_unsafe_structfp: @@ -4195,8 +4173,6 @@ define amdgpu_kernel void @global_atomic_fadd_uni_address_div_value_agent_scope_ ; GFX1132-DPP-NEXT: s_waitcnt lgkmcnt(0) ; GFX1132-DPP-NEXT: global_atomic_add_f32 v4, v0, s[0:1] ; GFX1132-DPP-NEXT: .LBB6_2: -; GFX1132-DPP-NEXT: s_nop 0 -; GFX1132-DPP-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX1132-DPP-NEXT: s_endpgm %divValue = call float @div.float.value() %result = atomicrmw fadd ptr addrspace(1) %ptr, float %divValue syncscope("agent") monotonic diff --git a/llvm/test/CodeGen/AMDGPU/promote-constOffset-to-imm.ll b/llvm/test/CodeGen/AMDGPU/promote-constOffset-to-imm.ll index 8081d40f7e665..b6afb7cf8c9a1 100644 --- a/llvm/test/CodeGen/AMDGPU/promote-constOffset-to-imm.ll +++ b/llvm/test/CodeGen/AMDGPU/promote-constOffset-to-imm.ll @@ -300,8 +300,6 @@ define amdgpu_kernel void @clmem_read_simplified(ptr addrspace(1) %buffer) { ; GFX11-NEXT: v_add_co_u32 v0, vcc_lo, v0, v2 ; GFX11-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, v1, v3, vcc_lo ; GFX11-NEXT: global_store_b64 v16, v[0:1], s[34:35] -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm entry: %call = tail call i64 @_Z13get_global_idj(i32 0) @@ -930,8 +928,6 @@ define hidden amdgpu_kernel void @clmem_read(ptr addrspace(1) %buffer) { ; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) ; GFX11-NEXT: v_add_co_ci_u32_e64 v1, null, s35, 0, s0 ; GFX11-NEXT: global_store_b64 v[0:1], v[2:3], off -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm entry: %call = tail call i64 @_Z13get_global_idj(i32 0) @@ -1294,8 +1290,6 @@ define amdgpu_kernel void @Address32(ptr addrspace(1) %buffer) { ; GFX11-NEXT: s_waitcnt vmcnt(0) ; GFX11-NEXT: v_add3_u32 v0, v3, v1, v0 ; GFX11-NEXT: global_store_b32 v6, v0, s[34:35] -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm entry: %call = tail call i64 @_Z13get_global_idj(i32 0) @@ -1543,8 +1537,6 @@ define amdgpu_kernel void @Offset64(ptr addrspace(1) %buffer) { ; GFX11-NEXT: v_add_co_u32 v0, vcc_lo, v4, v0 ; GFX11-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, v5, v1, vcc_lo ; GFX11-NEXT: global_store_b64 v8, v[0:1], s[34:35] -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm entry: %call = tail call i64 @_Z13get_global_idj(i32 0) @@ -1753,8 +1745,6 @@ define amdgpu_kernel void @p32Offset64(ptr addrspace(1) %buffer) { ; GFX11-NEXT: s_delay_alu instid0(VALU_DEP_1) ; GFX11-NEXT: v_add3_u32 v0, v2, v0, v3 ; GFX11-NEXT: global_store_b32 v6, v0, s[34:35] -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm entry: %call = tail call i64 @_Z13get_global_idj(i32 0) @@ -2017,8 +2007,6 @@ define amdgpu_kernel void @DiffBase(ptr addrspace(1) %buffer1, ; GFX11-NEXT: v_add_co_u32 v0, vcc_lo, v0, v2 ; GFX11-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, v1, v3, vcc_lo ; GFX11-NEXT: global_store_b64 v12, v[0:1], s[36:37] -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm ptr addrspace(1) %buffer2) { entry: @@ -2349,8 +2337,6 @@ define amdgpu_kernel void @ReverseOrder(ptr addrspace(1) %buffer) { ; GFX11-NEXT: v_add_co_u32 v0, vcc_lo, v0, v2 ; GFX11-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, v1, v3, vcc_lo ; GFX11-NEXT: global_store_b64 v16, v[0:1], s[34:35] -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm entry: %call = tail call i64 @_Z13get_global_idj(i32 0) @@ -2553,8 +2539,6 @@ define hidden amdgpu_kernel void @negativeoffset(ptr addrspace(1) nocapture %buf ; GFX11-NEXT: v_add_co_u32 v0, vcc_lo, v2, v0 ; GFX11-NEXT: v_add_co_ci_u32_e32 v1, vcc_lo, v3, v1, vcc_lo ; GFX11-NEXT: global_store_b64 v4, v[0:1], s[34:35] -; GFX11-NEXT: s_nop 0 -; GFX11-NEXT: s_sendmsg sendmsg(MSG_DEALLOC_VGPRS) ; GFX11-NEXT: s_endpgm entry: %call = tail call i64 @_Z13get_global_idj(i32 0) #2 diff --git a/llvm/test/CodeGen/AMDGPU/release-vgprs.mir b/llvm/test/CodeGen/AMDGPU/release-vgprs.mir index 07f8567ac0682..e80585299b91a 100644 --- a/llvm/test/CodeGen/AMDGPU/release-vgprs.mir +++ b/llvm/test/CodeGen/AMDGPU/release-vgprs.mir @@ -22,6 +22,8 @@ define amdgpu_ps void @global_atomic() { ret void } define amdgpu_ps void @image_atomic() { ret void } define amdgpu_ps void @global_store_optnone() noinline optnone { ret void } + define amdgpu_cs void @with_calls() { ret void } + define fastcc void @with_tail_calls() { ret void } ... --- @@ -565,3 +567,33 @@ body: | S_WAITCNT_VSCNT undef $sgpr_null, 0 S_ENDPGM 0 ... + +--- +name: with_calls +frameInfo: + hasCalls: true +body: | + bb.0: + ; Make sure we don't send DEALLOC_VGPRS after a call, since there might be + ; scratch stores still in progress. + ; CHECK-LABEL: name: with_calls + ; CHECK-NOT: S_SENDMSG 3 + ; CHECK: S_ENDPGM 0 + GLOBAL_STORE_DWORD undef renamable $vgpr0_vgpr1, killed renamable $vgpr1, 0, 4, implicit $exec + $sgpr30_sgpr31 = SI_CALL undef renamable $sgpr4_sgpr5, 0, csr_amdgpu + S_ENDPGM 0 +... + +--- +name: with_tail_calls +frameInfo: + hasCalls: true +body: | + bb.0: + ; Make sure we don't send DEALLOC_VGPRS when there's a tail call, since the + ; only valid action after DEALLOC_VGPRS is to terminate the wave. + ; CHECK-LABEL: name: with_tail_calls + ; CHECK-NOT: S_SENDMSG 3 + GLOBAL_STORE_DWORD undef renamable $vgpr0_vgpr1, killed renamable $vgpr1, 0, 4, implicit $exec + SI_TCRETURN undef renamable $sgpr4_sgpr5, @with_tail_calls, 0, csr_amdgpu +... From c9c8f0c2fcf3b25ec310a75216f1d5b582ec343f Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Thu, 11 Jan 2024 08:26:23 +0000 Subject: [PATCH 009/841] [AMDGPU] Update tests for GFX12 errors and unsupported instructions (#77624) --- llvm/test/MC/AMDGPU/gfx12_err.s | 72 +++++++++++++++++++++++++ llvm/test/MC/AMDGPU/gfx12_unsupported.s | 27 ++++++++++ 2 files changed, 99 insertions(+) diff --git a/llvm/test/MC/AMDGPU/gfx12_err.s b/llvm/test/MC/AMDGPU/gfx12_err.s index b103d7cef9769..edc24f4cf4fe9 100644 --- a/llvm/test/MC/AMDGPU/gfx12_err.s +++ b/llvm/test/MC/AMDGPU/gfx12_err.s @@ -1,5 +1,77 @@ // RUN: not llvm-mc -arch=amdgcn -mcpu=gfx1200 -show-encoding %s 2>&1 | FileCheck --check-prefixes=GFX12-ERR --implicit-check-not=error: -strict-whitespace %s +v_cubesc_f32_e64_dpp v5, v1, v2, 12345678 row_shr:4 row_mask:0xf bank_mask:0xf +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_add3_u32_e64_dpp v5, v1, v2, 49812340 dpp8:[7,6,5,4,3,2,1,0] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_cvt_f32_i32_e64_dpp v5, s1 dpp8:[7,6,5,4,3,2,1,0] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_cvt_f32_i32_e64_dpp v5, s1 row_shl:15 row_mask:0xf bank_mask:0xf +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_cvt_f16_u16_e64_dpp v5, s1 dpp8:[7,6,5,4,3,2,1,0] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_cvt_f16_u16_e64_dpp v5, s1 row_shl:1 row_mask:0xf bank_mask:0xf +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +; disallow space between colons +v_dual_mul_f32 v0, v0, v2 : : v_dual_mul_f32 v1, v1, v3 +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: unknown token in expression + +// On GFX12, v_dot8_i32_i4 is a valid SP3 alias for v_dot8_i32_iu4. +// However, we intentionally leave it unimplemented because on other +// processors v_dot8_i32_i4 denotes an instruction of a different +// behaviour, which is considered potentially dangerous. +v_dot8_i32_i4 v0, v1, v2, v3 +// GFX12-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + +// On GFX12, v_dot4_i32_i8 is a valid SP3 alias for v_dot4_i32_iu8. +// However, we intentionally leave it unimplemented because on other +// processors v_dot4_i32_i8 denotes an instruction of a different +// behaviour, which is considered potentially dangerous. +v_dot4_i32_i8 v0, v1, v2, v3 +// GFX12-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + +v_dot4c_i32_i8 v0, v1, v2 +// GFX12-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + +v_cmp_class_f16_e64_dpp s105, s2, v2 row_ror:15 +// GFX12-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_cmpx_class_f32_e64_dpp s1, v2 dpp8:[7,6,5,4,3,2,1,0] fi:1 +// GFX12-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_fma_mix_f32_e64_dpp v5, s1, v3, v4 quad_perm:[3,2,1,0] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_fma_mix_f32_e64_dpp v5, v1, s3, v4 quad_perm:[3,2,1,0] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_fma_mix_f32_e64_dpp v5, s1, v3, v4 dpp8:[7,6,5,4,3,2,1,0] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_fma_mix_f32_e64_dpp v5, v1, s3, v4 dpp8:[7,6,5,4,3,2,1,0] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_fma_mixhi_f16_e64_dpp v5, v1, 0, v4 quad_perm:[3,2,1,0] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_fma_mixlo_f16_e64_dpp v5, v1, 1, v4 dpp8:[7,6,5,4,3,2,1,0] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction + +v_lshlrev_b64 v[5:6], s2, s[0:1] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand (violates constant bus restrictions) + +v_lshrrev_b64 v[5:6], s2, s[0:1] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand (violates constant bus restrictions) + +v_ashrrev_i64 v[5:6], s2, s[0:1] +// GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand (violates constant bus restrictions) + image_load v0, v0, s[0:7] dmask:0x1 dim:SQ_RSRC_IMG_1D th:0x7 // GFX12-ERR: [[@LINE-1]]:{{[0-9]+}}: error: expected an identifier diff --git a/llvm/test/MC/AMDGPU/gfx12_unsupported.s b/llvm/test/MC/AMDGPU/gfx12_unsupported.s index aabaf526dc2a8..bf8f7437c0420 100644 --- a/llvm/test/MC/AMDGPU/gfx12_unsupported.s +++ b/llvm/test/MC/AMDGPU/gfx12_unsupported.s @@ -34,6 +34,18 @@ s_cbranch_cdbgsys_or_user 0 s_cbranch_cdbgsys_and_user 0 // CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU +v_fmac_legacy_f32 v0, v1, v2 +// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + +v_dot2c_f32_f16 v0, v1, v2 +// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + +v_dual_max_f32 v0, v1, v2 :: v_dual_max_f32 v3, v4, v5 +// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + +v_dual_min_f32 v0, v1, v2 :: v_dual_min_f32 v3, v4, v5 +// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + ds_cmpstore_f32 v0, v1, v2 // CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU @@ -91,6 +103,15 @@ s_cmpk_lt_u32 s0, 0 s_cmpk_le_u32 s0, 0 // CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU +buffer_atomic_cmpswap_f32 v[5:6], off, s[96:99], s3 +// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + +flat_atomic_cmpswap_f32 v[5:6], off, s[96:99], s3 +// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + +global_atomic_cmpswap_f32 v[5:6], off, s[96:99], s3 +// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + ds_gws_sema_release_all gds // CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU @@ -208,6 +229,12 @@ buffer_gl1_inv buffer_wbinvl1 // CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU +flat_atomic_csub v1, v[0:1], v2 offset:64 th:TH_ATOMIC_RETURN +// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: invalid instruction + +ds_add_f32 v255, v255 offset:4 gds +// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: gds modifier is not supported on this GPU + buffer_load_lds_b32 off, s[8:11], s3 // CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU From 66eedd1dd370d22ddf994540c20848618d64d1a6 Mon Sep 17 00:00:00 2001 From: hanbeom Date: Thu, 11 Jan 2024 17:34:30 +0900 Subject: [PATCH 010/841] [InstCombine] Fix worklist management in select fold (#77738) `InstCombine` uses `Worklist` to manage change history. `setOperand`, which was previously used to change the `Select` Instruction, does not, so it is `run` twice, which causes an `LLVM ERROR`. This problem is resolved by changing `setOperand` to `replaceOperand` as the change history will be registered in the Worklist. Fixes #77553. --- .../Transforms/InstCombine/InstCombineSelect.cpp | 4 ++-- llvm/test/Transforms/InstCombine/select.ll | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index ab55f235920a7..21bfc91148bfe 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -1704,11 +1704,11 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI, if (CmpRHS != CmpLHS && isa(CmpRHS) && !isa(CmpLHS)) { if (CmpLHS == TrueVal && Pred == ICmpInst::ICMP_EQ) { // Transform (X == C) ? X : Y -> (X == C) ? C : Y - SI.setOperand(1, CmpRHS); + replaceOperand(SI, 1, CmpRHS); Changed = true; } else if (CmpLHS == FalseVal && Pred == ICmpInst::ICMP_NE) { // Transform (X != C) ? Y : X -> (X != C) ? Y : C - SI.setOperand(2, CmpRHS); + replaceOperand(SI, 2, CmpRHS); Changed = true; } } diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index d3e959b1eaa0e..c5f1b77c6d740 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -3658,3 +3658,17 @@ loop: exit: ret i32 %rem } + +; (X == C) ? X : Y -> (X == C) ? C : Y +; Fixed #77553 +define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) { +; CHECK-LABEL: @src_select_xxory_eq0_xorxy_y( +; CHECK-NEXT: [[XOR0:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[COND:%.*]] = select i1 [[XOR0]], i32 0, i32 [[Y]] +; CHECK-NEXT: ret i32 [[COND]] +; + %xor = xor i32 %x, %y + %xor0 = icmp eq i32 %xor, 0 + %cond = select i1 %xor0, i32 %xor, i32 %y + ret i32 %cond +} From 158d72d728261c1e54dc77931372b2322c52849f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 11 Jan 2024 09:46:54 +0100 Subject: [PATCH 011/841] [Clang] Set writable and dead_on_unwind attributes on sret arguments (#77116) Set the writable and dead_on_unwind attributes for sret arguments. These indicate that the argument points to writable memory (and it's legal to introduce spurious writes to it on entry to the function) and that the argument memory will not be used if the call unwinds. This enables additional MemCpyOpt/DSE/LICM optimizations. --- clang/lib/CodeGen/CGCall.cpp | 2 + .../test/CodeGen/2006-05-19-SingleEltReturn.c | 4 +- clang/test/CodeGen/64bit-swiftcall.c | 22 +-- clang/test/CodeGen/CSKY/csky-abi.c | 4 +- clang/test/CodeGen/CSKY/csky-hard-abi.c | 44 +++--- clang/test/CodeGen/CSKY/csky-soft-abi.c | 44 +++--- clang/test/CodeGen/PowerPC/aix-alignment.c | 4 +- .../test/CodeGen/PowerPC/powerpc-c99complex.c | 6 +- .../CodeGen/PowerPC/ppc-aggregate-abi.cpp | 22 +-- .../PowerPC/ppc32-and-aix-struct-return.c | 22 +-- .../test/CodeGen/PowerPC/ppc64-align-struct.c | 16 +- clang/test/CodeGen/PowerPC/ppc64-elf-abi.c | 2 +- clang/test/CodeGen/PowerPC/ppc64-soft-float.c | 46 +++--- clang/test/CodeGen/PowerPC/ppc64-vector.c | 4 +- .../test/CodeGen/PowerPC/ppc64le-aggregates.c | 12 +- .../CodeGen/PowerPC/ppc64le-f128Aggregates.c | 4 +- clang/test/CodeGen/RISCV/bfloat-abi.c | 4 +- clang/test/CodeGen/RISCV/riscv-abi.cpp | 8 +- clang/test/CodeGen/RISCV/riscv32-abi.c | 66 ++++---- clang/test/CodeGen/RISCV/riscv64-abi.c | 10 +- .../SystemZ/gnu-atomic-builtins-i128-8Al.c | 54 ++----- .../test/CodeGen/SystemZ/systemz-abi-vector.c | 124 +++++++-------- clang/test/CodeGen/SystemZ/systemz-abi.c | 94 ++++++------ clang/test/CodeGen/SystemZ/systemz-abi.cpp | 36 ++--- .../test/CodeGen/SystemZ/systemz-inline-asm.c | 2 +- .../test/CodeGen/WebAssembly/wasm-arguments.c | 12 +- clang/test/CodeGen/WebAssembly/wasm-varargs.c | 4 +- .../CodeGen/X86/x86_32-arguments-darwin.c | 18 +-- .../test/CodeGen/X86/x86_32-arguments-iamcu.c | 2 +- .../test/CodeGen/X86/x86_64-arguments-nacl.c | 2 +- .../test/CodeGen/X86/x86_64-arguments-win32.c | 2 +- clang/test/CodeGen/X86/x86_64-arguments.c | 6 +- ...-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c | 2 +- clang/test/CodeGen/aarch64-varargs.c | 4 +- clang/test/CodeGen/aggregate-assign-call.c | 4 +- clang/test/CodeGen/aligned-sret.c | 2 +- clang/test/CodeGen/arc/arguments.c | 8 +- clang/test/CodeGen/arm-aapcs-vfp.c | 2 +- clang/test/CodeGen/arm-arguments.c | 28 ++-- clang/test/CodeGen/arm-homogenous.c | 8 +- clang/test/CodeGen/arm-neon-vld.c | 144 +++++++++--------- clang/test/CodeGen/arm-swiftcall.c | 26 ++-- clang/test/CodeGen/arm-varargs.c | 18 +-- clang/test/CodeGen/arm-vector-arguments.c | 6 +- clang/test/CodeGen/arm-vfp16-arguments.c | 2 +- clang/test/CodeGen/arm-vfp16-arguments2.cpp | 10 +- clang/test/CodeGen/arm64-arguments.c | 4 +- .../CodeGen/arm64-microsoft-arguments.cpp | 34 ++--- clang/test/CodeGen/arm64_32.c | 2 +- clang/test/CodeGen/armv7k-abi.c | 2 +- clang/test/CodeGen/attr-noundef.cpp | 6 +- clang/test/CodeGen/blocks.c | 2 +- clang/test/CodeGen/c11atomics-ios.c | 4 +- clang/test/CodeGen/c11atomics.c | 4 +- clang/test/CodeGen/ext-int-cc.c | 124 +++++++-------- clang/test/CodeGen/isfpclass.c | 2 +- clang/test/CodeGen/lanai-arguments.c | 4 +- clang/test/CodeGen/mcu-struct-return.c | 4 +- clang/test/CodeGen/mingw-long-double.c | 8 +- clang/test/CodeGen/mips-vector-return.c | 6 +- clang/test/CodeGen/mips-zero-sized-struct.c | 2 +- .../test/CodeGen/mips64-nontrivial-return.cpp | 2 +- clang/test/CodeGen/mips64-padding-arg.c | 6 +- clang/test/CodeGen/ms_abi.c | 4 +- clang/test/CodeGen/paren-list-agg-init.cpp | 6 +- clang/test/CodeGen/regcall2.c | 2 +- clang/test/CodeGen/regparm-struct.c | 2 +- clang/test/CodeGen/renderscript.c | 18 +-- clang/test/CodeGen/sparcv9-abi.c | 2 +- clang/test/CodeGen/sret.c | 10 +- clang/test/CodeGen/vectorcall.c | 4 +- clang/test/CodeGen/windows-struct-abi.c | 2 +- clang/test/CodeGen/windows-swiftcall.c | 4 +- clang/test/CodeGenCXX/aix-alignment.cpp | 2 +- clang/test/CodeGenCXX/arm-cc.cpp | 2 +- clang/test/CodeGenCXX/arm-swiftcall.cpp | 2 +- clang/test/CodeGenCXX/attr-musttail.cpp | 6 +- .../CodeGenCXX/call-with-static-chain.cpp | 4 +- clang/test/CodeGenCXX/conditional-gnu-ext.cpp | 8 +- clang/test/CodeGenCXX/cxx1z-copy-omission.cpp | 4 +- .../CodeGenCXX/cxx1z-lambda-star-this.cpp | 4 +- clang/test/CodeGenCXX/exceptions.cpp | 6 +- .../CodeGenCXX/homogeneous-aggregates.cpp | 28 ++-- clang/test/CodeGenCXX/lambda-expressions.cpp | 4 +- clang/test/CodeGenCXX/matrix-casts.cpp | 4 +- .../test/CodeGenCXX/matrix-type-builtins.cpp | 8 +- clang/test/CodeGenCXX/matrix-type.cpp | 2 +- .../CodeGenCXX/microsoft-abi-byval-sret.cpp | 4 +- .../CodeGenCXX/microsoft-abi-byval-thunks.cpp | 4 +- .../microsoft-abi-cdecl-method-sret.cpp | 8 +- .../CodeGenCXX/microsoft-abi-eh-cleanups.cpp | 8 +- .../microsoft-abi-sret-and-byval.cpp | 88 +++++------ .../CodeGenCXX/microsoft-abi-unknown-arch.cpp | 2 +- .../microsoft-abi-vmemptr-conflicts.cpp | 2 +- clang/test/CodeGenCXX/ms-thread_local.cpp | 4 +- clang/test/CodeGenCXX/nrvo.cpp | 18 +-- .../test/CodeGenCXX/pass-by-value-noalias.cpp | 4 +- clang/test/CodeGenCXX/regcall.cpp | 8 +- clang/test/CodeGenCXX/regcall4.cpp | 8 +- .../CodeGenCXX/stack-reuse-miscompile.cpp | 2 +- clang/test/CodeGenCXX/stack-reuse.cpp | 2 +- clang/test/CodeGenCXX/temporaries.cpp | 12 +- .../CodeGenCXX/thiscall-struct-return.cpp | 4 +- .../CodeGenCXX/thunk-returning-memptr.cpp | 4 +- clang/test/CodeGenCXX/trivial_abi.cpp | 8 +- clang/test/CodeGenCXX/unknown-anytype.cpp | 2 +- clang/test/CodeGenCXX/wasm-args-returns.cpp | 18 +-- clang/test/CodeGenCXX/x86_32-arguments.cpp | 8 +- clang/test/CodeGenCXX/x86_64-arguments.cpp | 4 +- clang/test/CodeGenCoroutines/coro-await.cpp | 10 +- clang/test/CodeGenCoroutines/coro-gro2.cpp | 10 +- clang/test/CodeGenHLSL/sret_output.hlsl | 2 +- clang/test/CodeGenObjC/arc.m | 4 +- clang/test/CodeGenObjC/direct-method.m | 2 +- .../nontrivial-c-struct-exception.m | 4 +- .../objc-non-trivial-struct-nrvo.m | 6 +- clang/test/CodeGenObjC/stret-1.m | 8 +- clang/test/CodeGenObjC/stret_lookup.m | 4 +- clang/test/CodeGenObjC/weak-in-c-struct.m | 2 +- .../CodeGenObjC/x86_64-struct-return-gc.m | 2 +- .../test/CodeGenObjCXX/objc-struct-cxx-abi.mm | 2 +- .../CodeGenOpenCL/addr-space-struct-arg.cl | 6 +- .../amdgpu-abi-struct-arg-byref.cl | 4 +- .../CodeGenOpenCL/amdgpu-abi-struct-coerce.cl | 6 +- .../CodeGenOpenCLCXX/addrspace-of-this.clcpp | 4 +- clang/test/Modules/templates.mm | 2 +- clang/test/OpenMP/irbuilder_for_iterator.cpp | 2 +- clang/test/OpenMP/irbuilder_for_rangefor.cpp | 6 +- .../master_taskloop_in_reduction_codegen.cpp | 4 +- ...ter_taskloop_simd_in_reduction_codegen.cpp | 4 +- .../OpenMP/target_in_reduction_codegen.cpp | 4 +- .../test/OpenMP/task_in_reduction_codegen.cpp | 4 +- .../OpenMP/taskloop_in_reduction_codegen.cpp | 4 +- .../taskloop_simd_in_reduction_codegen.cpp | 4 +- 134 files changed, 815 insertions(+), 837 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 51a43b5f85b3c..13677cf150aed 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2612,6 +2612,8 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, if (IRFunctionArgs.hasSRetArg()) { llvm::AttrBuilder SRETAttrs(getLLVMContext()); SRETAttrs.addStructRetAttr(getTypes().ConvertTypeForMem(RetTy)); + SRETAttrs.addAttribute(llvm::Attribute::Writable); + SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind); hasUsedSRet = true; if (RetAI.getInReg()) SRETAttrs.addAttribute(llvm::Attribute::InReg); diff --git a/clang/test/CodeGen/2006-05-19-SingleEltReturn.c b/clang/test/CodeGen/2006-05-19-SingleEltReturn.c index 16eacf3ec1625..b542242606cc3 100644 --- a/clang/test/CodeGen/2006-05-19-SingleEltReturn.c +++ b/clang/test/CodeGen/2006-05-19-SingleEltReturn.c @@ -24,7 +24,7 @@ struct Y bar(void) { // X86_32: define{{.*}} void @foo(ptr noundef %P) -// X86_32: call void @bar(ptr sret(%struct.Y) align 4 %{{[^),]*}}) +// X86_32: call void @bar(ptr dead_on_unwind writable sret(%struct.Y) align 4 %{{[^),]*}}) -// X86_32: define{{.*}} void @bar(ptr noalias sret(%struct.Y) align 4 %{{[^,)]*}}) +// X86_32: define{{.*}} void @bar(ptr dead_on_unwind noalias writable sret(%struct.Y) align 4 %{{[^,)]*}}) // X86_32: ret void diff --git a/clang/test/CodeGen/64bit-swiftcall.c b/clang/test/CodeGen/64bit-swiftcall.c index da6f18248c2af..b1c42e3b0a657 100644 --- a/clang/test/CodeGen/64bit-swiftcall.c +++ b/clang/test/CodeGen/64bit-swiftcall.c @@ -30,7 +30,7 @@ SWIFTCALL int indirect_result_2(OUT int *arg0, OUT float *arg1) { __builtin_unr typedef struct { char array[1024]; } struct_reallybig; SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); } -// CHECK-LABEL: define {{.*}} void @indirect_result_3(ptr noalias sret(%struct.struct_reallybig) {{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}) +// CHECK-LABEL: define {{.*}} void @indirect_result_3(ptr dead_on_unwind noalias writable sret(%struct.struct_reallybig) {{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}) SWIFTCALL void context_1(CONTEXT void *self) {} // CHECK-LABEL: define {{.*}} void @context_1(ptr swiftself @@ -238,7 +238,7 @@ typedef struct { } struct_big_1; TEST(struct_big_1) -// CHECK-LABEL: define {{.*}} void @return_struct_big_1({{.*}} noalias sret +// CHECK-LABEL: define {{.*}} void @return_struct_big_1(ptr dead_on_unwind noalias writable sret // Should not be byval. // CHECK-LABEL: define {{.*}} void @take_struct_big_1(ptr{{( %.*)?}}) @@ -522,7 +522,7 @@ typedef struct { double d4; } struct_d5; TEST(struct_d5) -// CHECK: define{{.*}} swiftcc void @return_struct_d5(ptr noalias sret([[STRUCT5:.+]]) +// CHECK: define{{.*}} swiftcc void @return_struct_d5(ptr dead_on_unwind noalias writable sret([[STRUCT5:.+]]) // CHECK: define{{.*}} swiftcc void @take_struct_d5(ptr typedef struct { @@ -709,7 +709,7 @@ typedef struct { long long l4; } struct_l5; TEST(struct_l5) -// CHECK: define{{.*}} swiftcc void @return_struct_l5(ptr noalias sret([[STRUCT5:.+]]) +// CHECK: define{{.*}} swiftcc void @return_struct_l5(ptr dead_on_unwind noalias writable sret([[STRUCT5:.+]]) // CHECK: define{{.*}} swiftcc void @take_struct_l5(ptr typedef struct { @@ -754,7 +754,7 @@ typedef struct { char16 c4; } struct_vc5; TEST(struct_vc5) -// CHECK: define{{.*}} swiftcc void @return_struct_vc5(ptr noalias sret([[STRUCT:.+]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vc5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]]) // CHECK: define{{.*}} swiftcc void @take_struct_vc5(ptr typedef struct { @@ -799,7 +799,7 @@ typedef struct { short8 c4; } struct_vs5; TEST(struct_vs5) -// CHECK: define{{.*}} swiftcc void @return_struct_vs5(ptr noalias sret([[STRUCT:.+]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vs5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]]) // CHECK: define{{.*}} swiftcc void @take_struct_vs5(ptr typedef struct { @@ -844,7 +844,7 @@ typedef struct { int4 c4; } struct_vi5; TEST(struct_vi5) -// CHECK: define{{.*}} swiftcc void @return_struct_vi5(ptr noalias sret([[STRUCT:.+]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vi5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]]) // CHECK: define{{.*}} swiftcc void @take_struct_vi5(ptr typedef struct { @@ -872,7 +872,7 @@ typedef struct { long2 c4; } struct_vl5; TEST(struct_vl5) -// CHECK: define{{.*}} swiftcc void @return_struct_vl5(ptr noalias sret([[STRUCT:.+]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vl5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]]) // CHECK: define{{.*}} swiftcc void @take_struct_vl5(ptr typedef struct { @@ -900,7 +900,7 @@ typedef struct { double2 c4; } struct_vd5; TEST(struct_vd5) -// CHECK: define{{.*}} swiftcc void @return_struct_vd5(ptr noalias sret([[STRUCT:.+]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vd5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]]) // CHECK: define{{.*}} swiftcc void @take_struct_vd5(ptr typedef struct { @@ -924,7 +924,7 @@ typedef struct { double4 c2; } struct_vd43; TEST(struct_vd43) -// CHECK: define{{.*}} swiftcc void @return_struct_vd43(ptr noalias sret([[STRUCT:.+]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vd43(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]]) // CHECK: define{{.*}} swiftcc void @take_struct_vd43(ptr typedef struct { @@ -960,7 +960,7 @@ typedef struct { float4 c4; } struct_vf5; TEST(struct_vf5) -// CHECK: define{{.*}} swiftcc void @return_struct_vf5(ptr noalias sret([[STRUCT:.+]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vf5(ptr dead_on_unwind noalias writable sret([[STRUCT:.+]]) // CHECK: define{{.*}} swiftcc void @take_struct_vf5(ptr typedef struct { diff --git a/clang/test/CodeGen/CSKY/csky-abi.c b/clang/test/CodeGen/CSKY/csky-abi.c index a24d4d8d64077..2e549376ba933 100644 --- a/clang/test/CodeGen/CSKY/csky-abi.c +++ b/clang/test/CodeGen/CSKY/csky-abi.c @@ -117,7 +117,7 @@ void f_agg_large(struct large x) { // The address where the struct should be written to will be the first // argument -// CHECK-LABEL: define{{.*}} void @f_agg_large_ret(ptr noalias sret(%struct.large) align 4 %agg.result, i32 noundef %i, i8 noundef signext %j) +// CHECK-LABEL: define{{.*}} void @f_agg_large_ret(ptr dead_on_unwind noalias writable sret(%struct.large) align 4 %agg.result, i32 noundef %i, i8 noundef signext %j) struct large f_agg_large_ret(int32_t i, int8_t j) { return (struct large){1, 2, 3, 4}; } @@ -144,7 +144,7 @@ int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c, // the presence of large return values that consume a register due to the need // to pass a pointer. -// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, i32 noundef %a, i64 noundef %b, i64 noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) +// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr dead_on_unwind noalias writable sret(%struct.large) align 4 %agg.result, i32 noundef %a, i64 noundef %b, i64 noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) struct large f_scalar_stack_2(int32_t a, int64_t b, int64_t c, long double d, uint8_t e, int8_t f, uint8_t g) { return (struct large){a, e, f, g}; diff --git a/clang/test/CodeGen/CSKY/csky-hard-abi.c b/clang/test/CodeGen/CSKY/csky-hard-abi.c index 2171da8091e2b..0bc4a5a8808e5 100644 --- a/clang/test/CodeGen/CSKY/csky-hard-abi.c +++ b/clang/test/CodeGen/CSKY/csky-hard-abi.c @@ -72,7 +72,7 @@ struct double_float_s { // CHECK: define{{.*}} void @f_double_double_s_arg([4 x i32] %a.coerce) void f_double_double_s_arg(struct double_double_s a) {} -// CHECK: define{{.*}} void @f_ret_double_double_s(ptr noalias sret(%struct.double_double_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_double_s(ptr dead_on_unwind noalias writable sret(%struct.double_double_s) align 4 %agg.result) struct double_double_s f_ret_double_double_s(void) { return (struct double_double_s){1.0, 2.0}; } @@ -80,7 +80,7 @@ struct double_double_s f_ret_double_double_s(void) { // CHECK: define{{.*}} void @f_double_float_s_arg([3 x i32] %a.coerce) void f_double_float_s_arg(struct double_float_s a) {} -// CHECK: define{{.*}} void @f_ret_double_float_s(ptr noalias sret(%struct.double_float_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_float_s(ptr dead_on_unwind noalias writable sret(%struct.double_float_s) align 4 %agg.result) struct double_float_s f_ret_double_float_s(void) { return (struct double_float_s){1.0, 2.0}; } @@ -118,7 +118,7 @@ struct double_int8_zbf_s { // CHECK: define{{.*}} @f_double_int8_s_arg([3 x i32] %a.coerce) void f_double_int8_s_arg(struct double_int8_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int8_s(ptr noalias sret(%struct.double_int8_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int8_s(ptr dead_on_unwind noalias writable sret(%struct.double_int8_s) align 4 %agg.result) struct double_int8_s f_ret_double_int8_s(void) { return (struct double_int8_s){1.0, 2}; } @@ -126,7 +126,7 @@ struct double_int8_s f_ret_double_int8_s(void) { // CHECK: define{{.*}} void @f_double_uint8_s_arg([3 x i32] %a.coerce) void f_double_uint8_s_arg(struct double_uint8_s a) {} -// CHECK: define{{.*}} void @f_ret_double_uint8_s(ptr noalias sret(%struct.double_uint8_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_uint8_s(ptr dead_on_unwind noalias writable sret(%struct.double_uint8_s) align 4 %agg.result) struct double_uint8_s f_ret_double_uint8_s(void) { return (struct double_uint8_s){1.0, 2}; } @@ -134,7 +134,7 @@ struct double_uint8_s f_ret_double_uint8_s(void) { // CHECK: define{{.*}} void @f_double_int32_s_arg([3 x i32] %a.coerce) void f_double_int32_s_arg(struct double_int32_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int32_s(ptr noalias sret(%struct.double_int32_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int32_s(ptr dead_on_unwind noalias writable sret(%struct.double_int32_s) align 4 %agg.result) struct double_int32_s f_ret_double_int32_s(void) { return (struct double_int32_s){1.0, 2}; } @@ -142,7 +142,7 @@ struct double_int32_s f_ret_double_int32_s(void) { // CHECK: define{{.*}} void @f_double_int64_s_arg([4 x i32] %a.coerce) void f_double_int64_s_arg(struct double_int64_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int64_s(ptr noalias sret(%struct.double_int64_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int64_s(ptr dead_on_unwind noalias writable sret(%struct.double_int64_s) align 4 %agg.result) struct double_int64_s f_ret_double_int64_s(void) { return (struct double_int64_s){1.0, 2}; } @@ -150,7 +150,7 @@ struct double_int64_s f_ret_double_int64_s(void) { // CHECK: define{{.*}} void @f_double_int64bf_s_arg([3 x i32] %a.coerce) void f_double_int64bf_s_arg(struct double_int64bf_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int64bf_s(ptr noalias sret(%struct.double_int64bf_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int64bf_s(ptr dead_on_unwind noalias writable sret(%struct.double_int64bf_s) align 4 %agg.result) struct double_int64bf_s f_ret_double_int64bf_s(void) { return (struct double_int64bf_s){1.0, 2}; } @@ -158,7 +158,7 @@ struct double_int64bf_s f_ret_double_int64bf_s(void) { // CHECK: define{{.*}} void @f_double_int8_zbf_s([3 x i32] %a.coerce) void f_double_int8_zbf_s(struct double_int8_zbf_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int8_zbf_s(ptr noalias sret(%struct.double_int8_zbf_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int8_zbf_s(ptr dead_on_unwind noalias writable sret(%struct.double_int8_zbf_s) align 4 %agg.result) struct double_int8_zbf_s f_ret_double_int8_zbf_s(void) { return (struct double_int8_zbf_s){1.0, 2}; } @@ -179,7 +179,7 @@ void f_struct_double_int8_insufficient_fprs(float a, double b, double c, double // CHECK: define{{.*}} void @f_doublecomplex(double noundef %a.coerce0, double noundef %a.coerce1) void f_doublecomplex(double __complex__ a) {} -// CHECK: define{{.*}} void @f_ret_doublecomplex(ptr noalias sret({ double, double }) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublecomplex(ptr dead_on_unwind noalias writable sret({ double, double }) align 4 %agg.result) double __complex__ f_ret_doublecomplex(void) { return 1.0; } @@ -191,7 +191,7 @@ struct doublecomplex_s { // CHECK: define{{.*}} void @f_doublecomplex_s_arg([4 x i32] %a.coerce) void f_doublecomplex_s_arg(struct doublecomplex_s a) {} -// CHECK: define{{.*}} void @f_ret_doublecomplex_s(ptr noalias sret(%struct.doublecomplex_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublecomplex_s(ptr dead_on_unwind noalias writable sret(%struct.doublecomplex_s) align 4 %agg.result) struct doublecomplex_s f_ret_doublecomplex_s(void) { return (struct doublecomplex_s){1.0}; } @@ -218,7 +218,7 @@ struct doublearr2_s { // CHECK: define{{.*}} void @f_doublearr2_s_arg([4 x i32] %a.coerce) void f_doublearr2_s_arg(struct doublearr2_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_s(ptr noalias sret(%struct.doublearr2_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_s) align 4 %agg.result) struct doublearr2_s f_ret_doublearr2_s(void) { return (struct doublearr2_s){{1.0, 2.0}}; } @@ -232,7 +232,7 @@ struct doublearr2_tricky1_s { // CHECK: define{{.*}} void @f_doublearr2_tricky1_s_arg([4 x i32] %a.coerce) void f_doublearr2_tricky1_s_arg(struct doublearr2_tricky1_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_tricky1_s(ptr noalias sret(%struct.doublearr2_tricky1_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_tricky1_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky1_s) align 4 %agg.result) struct doublearr2_tricky1_s f_ret_doublearr2_tricky1_s(void) { return (struct doublearr2_tricky1_s){{{{1.0}}, {{2.0}}}}; } @@ -247,7 +247,7 @@ struct doublearr2_tricky2_s { // CHECK: define{{.*}} void @f_doublearr2_tricky2_s_arg([4 x i32] %a.coerce) void f_doublearr2_tricky2_s_arg(struct doublearr2_tricky2_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_tricky2_s(ptr noalias sret(%struct.doublearr2_tricky2_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_tricky2_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky2_s) align 4 %agg.result) struct doublearr2_tricky2_s f_ret_doublearr2_tricky2_s(void) { return (struct doublearr2_tricky2_s){{}, {{{1.0}}, {{2.0}}}}; } @@ -262,7 +262,7 @@ struct doublearr2_tricky3_s { // CHECK: define{{.*}} void @f_doublearr2_tricky3_s_arg([4 x i32] %a.coerce) void f_doublearr2_tricky3_s_arg(struct doublearr2_tricky3_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_tricky3_s(ptr noalias sret(%struct.doublearr2_tricky3_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_tricky3_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky3_s) align 4 %agg.result) struct doublearr2_tricky3_s f_ret_doublearr2_tricky3_s(void) { return (struct doublearr2_tricky3_s){{}, {{{1.0}}, {{2.0}}}}; } @@ -278,7 +278,7 @@ struct doublearr2_tricky4_s { // CHECK: define{{.*}} void @f_doublearr2_tricky4_s_arg([4 x i32] %a.coerce) void f_doublearr2_tricky4_s_arg(struct doublearr2_tricky4_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_tricky4_s(ptr noalias sret(%struct.doublearr2_tricky4_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_tricky4_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky4_s) align 4 %agg.result) struct doublearr2_tricky4_s f_ret_doublearr2_tricky4_s(void) { return (struct doublearr2_tricky4_s){{}, {{{}, {1.0}}, {{}, {2.0}}}}; } @@ -292,7 +292,7 @@ struct int_double_int_s { // CHECK: define{{.*}} void @f_int_double_int_s_arg([4 x i32] %a.coerce) void f_int_double_int_s_arg(struct int_double_int_s a) {} -// CHECK: define{{.*}} void @f_ret_int_double_int_s(ptr noalias sret(%struct.int_double_int_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_int_double_int_s(ptr dead_on_unwind noalias writable sret(%struct.int_double_int_s) align 4 %agg.result) struct int_double_int_s f_ret_int_double_int_s(void) { return (struct int_double_int_s){1, 2.0, 3}; } @@ -305,7 +305,7 @@ struct int64_double_s { // CHECK: define{{.*}} void @f_int64_double_s_arg([4 x i32] %a.coerce) void f_int64_double_s_arg(struct int64_double_s a) {} -// CHECK: define{{.*}} void @f_ret_int64_double_s(ptr noalias sret(%struct.int64_double_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_int64_double_s(ptr dead_on_unwind noalias writable sret(%struct.int64_double_s) align 4 %agg.result) struct int64_double_s f_ret_int64_double_s(void) { return (struct int64_double_s){1, 2.0}; } @@ -319,7 +319,7 @@ struct char_char_double_s { // CHECK-LABEL: define{{.*}} void @f_char_char_double_s_arg([3 x i32] %a.coerce) void f_char_char_double_s_arg(struct char_char_double_s a) {} -// CHECK: define{{.*}} void @f_ret_char_char_double_s(ptr noalias sret(%struct.char_char_double_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_char_char_double_s(ptr dead_on_unwind noalias writable sret(%struct.char_char_double_s) align 4 %agg.result) struct char_char_double_s f_ret_char_char_double_s(void) { return (struct char_char_double_s){1, 2, 3.0}; } @@ -338,19 +338,19 @@ union double_u f_ret_double_u(void) { return (union double_u){1.0}; } -// CHECK: define{{.*}} void @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs(ptr noalias sret(%struct.double_int32_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) +// CHECK: define{{.*}} void @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs(ptr dead_on_unwind noalias writable sret(%struct.double_int32_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) struct double_int32_s f_ret_double_int32_s_double_int32_s_just_sufficient_gprs( int a, int b, int c, int d, int e, int f, int g, struct double_int32_s h) { return (struct double_int32_s){1.0, 2}; } -// CHECK: define{{.*}} void @f_ret_double_double_s_double_int32_s_just_sufficient_gprs(ptr noalias sret(%struct.double_double_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) +// CHECK: define{{.*}} void @f_ret_double_double_s_double_int32_s_just_sufficient_gprs(ptr dead_on_unwind noalias writable sret(%struct.double_double_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) struct double_double_s f_ret_double_double_s_double_int32_s_just_sufficient_gprs( int a, int b, int c, int d, int e, int f, int g, struct double_int32_s h) { return (struct double_double_s){1.0, 2.0}; } -// CHECK: define{{.*}} void @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs(ptr noalias sret({ double, double }) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) +// CHECK: define{{.*}} void @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs(ptr dead_on_unwind noalias writable sret({ double, double }) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) double __complex__ f_ret_doublecomplex_double_int32_s_just_sufficient_gprs( int a, int b, int c, int d, int e, int f, int g, struct double_int32_s h) { return 1.0; @@ -376,7 +376,7 @@ struct large { // the presence of large return values that consume a register due to the need // to pass a pointer. -// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, float noundef %a, i64 noundef %b, double noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) +// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr dead_on_unwind noalias writable sret(%struct.large) align 4 %agg.result, float noundef %a, i64 noundef %b, double noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) struct large f_scalar_stack_2(float a, int64_t b, double c, long double d, uint8_t e, int8_t f, uint8_t g) { return (struct large){a, e, f, g}; diff --git a/clang/test/CodeGen/CSKY/csky-soft-abi.c b/clang/test/CodeGen/CSKY/csky-soft-abi.c index 1aba2df1f20a2..04fb7a4940842 100644 --- a/clang/test/CodeGen/CSKY/csky-soft-abi.c +++ b/clang/test/CodeGen/CSKY/csky-soft-abi.c @@ -72,7 +72,7 @@ struct double_float_s { // CHECK: define{{.*}} void @f_double_double_s_arg([4 x i32] %a.coerce) void f_double_double_s_arg(struct double_double_s a) {} -// CHECK: define{{.*}} void @f_ret_double_double_s(ptr noalias sret(%struct.double_double_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_double_s(ptr dead_on_unwind noalias writable sret(%struct.double_double_s) align 4 %agg.result) struct double_double_s f_ret_double_double_s(void) { return (struct double_double_s){1.0, 2.0}; } @@ -80,7 +80,7 @@ struct double_double_s f_ret_double_double_s(void) { // CHECK: define{{.*}} void @f_double_float_s_arg([3 x i32] %a.coerce) void f_double_float_s_arg(struct double_float_s a) {} -// CHECK: define{{.*}} void @f_ret_double_float_s(ptr noalias sret(%struct.double_float_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_float_s(ptr dead_on_unwind noalias writable sret(%struct.double_float_s) align 4 %agg.result) struct double_float_s f_ret_double_float_s(void) { return (struct double_float_s){1.0, 2.0}; } @@ -118,7 +118,7 @@ struct double_int8_zbf_s { // CHECK: define{{.*}} @f_double_int8_s_arg([3 x i32] %a.coerce) void f_double_int8_s_arg(struct double_int8_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int8_s(ptr noalias sret(%struct.double_int8_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int8_s(ptr dead_on_unwind noalias writable sret(%struct.double_int8_s) align 4 %agg.result) struct double_int8_s f_ret_double_int8_s(void) { return (struct double_int8_s){1.0, 2}; } @@ -126,7 +126,7 @@ struct double_int8_s f_ret_double_int8_s(void) { // CHECK: define{{.*}} void @f_double_uint8_s_arg([3 x i32] %a.coerce) void f_double_uint8_s_arg(struct double_uint8_s a) {} -// CHECK: define{{.*}} void @f_ret_double_uint8_s(ptr noalias sret(%struct.double_uint8_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_uint8_s(ptr dead_on_unwind noalias writable sret(%struct.double_uint8_s) align 4 %agg.result) struct double_uint8_s f_ret_double_uint8_s(void) { return (struct double_uint8_s){1.0, 2}; } @@ -134,7 +134,7 @@ struct double_uint8_s f_ret_double_uint8_s(void) { // CHECK: define{{.*}} void @f_double_int32_s_arg([3 x i32] %a.coerce) void f_double_int32_s_arg(struct double_int32_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int32_s(ptr noalias sret(%struct.double_int32_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int32_s(ptr dead_on_unwind noalias writable sret(%struct.double_int32_s) align 4 %agg.result) struct double_int32_s f_ret_double_int32_s(void) { return (struct double_int32_s){1.0, 2}; } @@ -142,7 +142,7 @@ struct double_int32_s f_ret_double_int32_s(void) { // CHECK: define{{.*}} void @f_double_int64_s_arg([4 x i32] %a.coerce) void f_double_int64_s_arg(struct double_int64_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int64_s(ptr noalias sret(%struct.double_int64_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int64_s(ptr dead_on_unwind noalias writable sret(%struct.double_int64_s) align 4 %agg.result) struct double_int64_s f_ret_double_int64_s(void) { return (struct double_int64_s){1.0, 2}; } @@ -150,7 +150,7 @@ struct double_int64_s f_ret_double_int64_s(void) { // CHECK: define{{.*}} void @f_double_int64bf_s_arg([3 x i32] %a.coerce) void f_double_int64bf_s_arg(struct double_int64bf_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int64bf_s(ptr noalias sret(%struct.double_int64bf_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int64bf_s(ptr dead_on_unwind noalias writable sret(%struct.double_int64bf_s) align 4 %agg.result) struct double_int64bf_s f_ret_double_int64bf_s(void) { return (struct double_int64bf_s){1.0, 2}; } @@ -158,7 +158,7 @@ struct double_int64bf_s f_ret_double_int64bf_s(void) { // CHECK: define{{.*}} void @f_double_int8_zbf_s([3 x i32] %a.coerce) void f_double_int8_zbf_s(struct double_int8_zbf_s a) {} -// CHECK: define{{.*}} void @f_ret_double_int8_zbf_s(ptr noalias sret(%struct.double_int8_zbf_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_double_int8_zbf_s(ptr dead_on_unwind noalias writable sret(%struct.double_int8_zbf_s) align 4 %agg.result) struct double_int8_zbf_s f_ret_double_int8_zbf_s(void) { return (struct double_int8_zbf_s){1.0, 2}; } @@ -180,7 +180,7 @@ void f_struct_double_int8_insufficient_fprs(float a, double b, double c, double // CHECK: define{{.*}} void @f_doublecomplex([4 x i32] noundef %a.coerce) void f_doublecomplex(double __complex__ a) {} -// CHECK: define{{.*}} void @f_ret_doublecomplex(ptr noalias sret({ double, double }) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublecomplex(ptr dead_on_unwind noalias writable sret({ double, double }) align 4 %agg.result) double __complex__ f_ret_doublecomplex(void) { return 1.0; } @@ -192,7 +192,7 @@ struct doublecomplex_s { // CHECK: define{{.*}} void @f_doublecomplex_s_arg([4 x i32] %a.coerce) void f_doublecomplex_s_arg(struct doublecomplex_s a) {} -// CHECK: define{{.*}} void @f_ret_doublecomplex_s(ptr noalias sret(%struct.doublecomplex_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublecomplex_s(ptr dead_on_unwind noalias writable sret(%struct.doublecomplex_s) align 4 %agg.result) struct doublecomplex_s f_ret_doublecomplex_s(void) { return (struct doublecomplex_s){1.0}; } @@ -219,7 +219,7 @@ struct doublearr2_s { // CHECK: define{{.*}} void @f_doublearr2_s_arg([4 x i32] %a.coerce) void f_doublearr2_s_arg(struct doublearr2_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_s(ptr noalias sret(%struct.doublearr2_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_s) align 4 %agg.result) struct doublearr2_s f_ret_doublearr2_s(void) { return (struct doublearr2_s){{1.0, 2.0}}; } @@ -233,7 +233,7 @@ struct doublearr2_tricky1_s { // CHECK: define{{.*}} void @f_doublearr2_tricky1_s_arg([4 x i32] %a.coerce) void f_doublearr2_tricky1_s_arg(struct doublearr2_tricky1_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_tricky1_s(ptr noalias sret(%struct.doublearr2_tricky1_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_tricky1_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky1_s) align 4 %agg.result) struct doublearr2_tricky1_s f_ret_doublearr2_tricky1_s(void) { return (struct doublearr2_tricky1_s){{{{1.0}}, {{2.0}}}}; } @@ -248,7 +248,7 @@ struct doublearr2_tricky2_s { // CHECK: define{{.*}} void @f_doublearr2_tricky2_s_arg([4 x i32] %a.coerce) void f_doublearr2_tricky2_s_arg(struct doublearr2_tricky2_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_tricky2_s(ptr noalias sret(%struct.doublearr2_tricky2_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_tricky2_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky2_s) align 4 %agg.result) struct doublearr2_tricky2_s f_ret_doublearr2_tricky2_s(void) { return (struct doublearr2_tricky2_s){{}, {{{1.0}}, {{2.0}}}}; } @@ -263,7 +263,7 @@ struct doublearr2_tricky3_s { // CHECK: define{{.*}} void @f_doublearr2_tricky3_s_arg([4 x i32] %a.coerce) void f_doublearr2_tricky3_s_arg(struct doublearr2_tricky3_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_tricky3_s(ptr noalias sret(%struct.doublearr2_tricky3_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_tricky3_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky3_s) align 4 %agg.result) struct doublearr2_tricky3_s f_ret_doublearr2_tricky3_s(void) { return (struct doublearr2_tricky3_s){{}, {{{1.0}}, {{2.0}}}}; } @@ -279,7 +279,7 @@ struct doublearr2_tricky4_s { // CHECK: define{{.*}} void @f_doublearr2_tricky4_s_arg([4 x i32] %a.coerce) void f_doublearr2_tricky4_s_arg(struct doublearr2_tricky4_s a) {} -// CHECK: define{{.*}} void @f_ret_doublearr2_tricky4_s(ptr noalias sret(%struct.doublearr2_tricky4_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_doublearr2_tricky4_s(ptr dead_on_unwind noalias writable sret(%struct.doublearr2_tricky4_s) align 4 %agg.result) struct doublearr2_tricky4_s f_ret_doublearr2_tricky4_s(void) { return (struct doublearr2_tricky4_s){{}, {{{}, {1.0}}, {{}, {2.0}}}}; } @@ -293,7 +293,7 @@ struct int_double_int_s { // CHECK: define{{.*}} void @f_int_double_int_s_arg([4 x i32] %a.coerce) void f_int_double_int_s_arg(struct int_double_int_s a) {} -// CHECK: define{{.*}} void @f_ret_int_double_int_s(ptr noalias sret(%struct.int_double_int_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_int_double_int_s(ptr dead_on_unwind noalias writable sret(%struct.int_double_int_s) align 4 %agg.result) struct int_double_int_s f_ret_int_double_int_s(void) { return (struct int_double_int_s){1, 2.0, 3}; } @@ -306,7 +306,7 @@ struct int64_double_s { // CHECK: define{{.*}} void @f_int64_double_s_arg([4 x i32] %a.coerce) void f_int64_double_s_arg(struct int64_double_s a) {} -// CHECK: define{{.*}} void @f_ret_int64_double_s(ptr noalias sret(%struct.int64_double_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_int64_double_s(ptr dead_on_unwind noalias writable sret(%struct.int64_double_s) align 4 %agg.result) struct int64_double_s f_ret_int64_double_s(void) { return (struct int64_double_s){1, 2.0}; } @@ -320,7 +320,7 @@ struct char_char_double_s { // CHECK-LABEL: define{{.*}} void @f_char_char_double_s_arg([3 x i32] %a.coerce) void f_char_char_double_s_arg(struct char_char_double_s a) {} -// CHECK: define{{.*}} void @f_ret_char_char_double_s(ptr noalias sret(%struct.char_char_double_s) align 4 %agg.result) +// CHECK: define{{.*}} void @f_ret_char_char_double_s(ptr dead_on_unwind noalias writable sret(%struct.char_char_double_s) align 4 %agg.result) struct char_char_double_s f_ret_char_char_double_s(void) { return (struct char_char_double_s){1, 2, 3.0}; } @@ -339,19 +339,19 @@ union double_u f_ret_double_u(void) { return (union double_u){1.0}; } -// CHECK: define{{.*}} void @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs(ptr noalias sret(%struct.double_int32_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) +// CHECK: define{{.*}} void @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs(ptr dead_on_unwind noalias writable sret(%struct.double_int32_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) struct double_int32_s f_ret_double_int32_s_double_int32_s_just_sufficient_gprs( int a, int b, int c, int d, int e, int f, int g, struct double_int32_s h) { return (struct double_int32_s){1.0, 2}; } -// CHECK: define{{.*}} void @f_ret_double_double_s_double_int32_s_just_sufficient_gprs(ptr noalias sret(%struct.double_double_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) +// CHECK: define{{.*}} void @f_ret_double_double_s_double_int32_s_just_sufficient_gprs(ptr dead_on_unwind noalias writable sret(%struct.double_double_s) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) struct double_double_s f_ret_double_double_s_double_int32_s_just_sufficient_gprs( int a, int b, int c, int d, int e, int f, int g, struct double_int32_s h) { return (struct double_double_s){1.0, 2.0}; } -// CHECK: define{{.*}} void @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs(ptr noalias sret({ double, double }) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) +// CHECK: define{{.*}} void @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs(ptr dead_on_unwind noalias writable sret({ double, double }) align 4 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e, i32 noundef %f, i32 noundef %g, [3 x i32] %h.coerce) double __complex__ f_ret_doublecomplex_double_int32_s_just_sufficient_gprs( int a, int b, int c, int d, int e, int f, int g, struct double_int32_s h) { return 1.0; @@ -377,7 +377,7 @@ struct large { // the presence of large return values that consume a register due to the need // to pass a pointer. -// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr noalias sret(%struct.large) align 4 %agg.result, float noundef %a, i64 noundef %b, double noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) +// CHECK-LABEL: define{{.*}} void @f_scalar_stack_2(ptr dead_on_unwind noalias writable sret(%struct.large) align 4 %agg.result, float noundef %a, i64 noundef %b, double noundef %c, double noundef %d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef zeroext %g) struct large f_scalar_stack_2(float a, int64_t b, double c, long double d, uint8_t e, int8_t f, uint8_t g) { return (struct large){a, e, f, g}; diff --git a/clang/test/CodeGen/PowerPC/aix-alignment.c b/clang/test/CodeGen/PowerPC/aix-alignment.c index e25fc7ec5599b..f732e94569ef2 100644 --- a/clang/test/CodeGen/PowerPC/aix-alignment.c +++ b/clang/test/CodeGen/PowerPC/aix-alignment.c @@ -22,8 +22,8 @@ StructDouble d1; // AIX: ret double %0 double retDouble(double x) { return x; } -// AIX32: define void @bar(ptr noalias sret(%struct.StructDouble) align 4 %agg.result, ptr noundef byval(%struct.StructDouble) align 4 %x) -// AIX64: define void @bar(ptr noalias sret(%struct.StructDouble) align 4 %agg.result, ptr noundef byval(%struct.StructDouble) align 8 %x) +// AIX32: define void @bar(ptr dead_on_unwind noalias writable sret(%struct.StructDouble) align 4 %agg.result, ptr noundef byval(%struct.StructDouble) align 4 %x) +// AIX64: define void @bar(ptr dead_on_unwind noalias writable sret(%struct.StructDouble) align 4 %agg.result, ptr noundef byval(%struct.StructDouble) align 8 %x) // AIX32: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %agg.result, ptr align 4 %x, i32 16, i1 false) // AIX64: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %agg.result, ptr align 8 %x, i64 16, i1 false) StructDouble bar(StructDouble x) { return x; } diff --git a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c index f01c7820857e8..82b5ac0fdc06c 100644 --- a/clang/test/CodeGen/PowerPC/powerpc-c99complex.c +++ b/clang/test/CodeGen/PowerPC/powerpc-c99complex.c @@ -9,7 +9,7 @@ _Complex float foo1(_Complex float x) { // CHECK-LABEL: define{{.*}} { float, float } @foo1(float noundef %x.{{.*}}, float noundef %x.{{.*}}) #0 { // CHECK: ret { float, float } -// PPC32LNX-LABEL: define{{.*}} void @foo1(ptr noalias sret({ float, float }) align 4 %agg.result, ptr noundef byval({ float, float }) align 4 %x) #0 { +// PPC32LNX-LABEL: define{{.*}} void @foo1(ptr dead_on_unwind noalias writable sret({ float, float }) align 4 %agg.result, ptr noundef byval({ float, float }) align 4 %x) #0 { // PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds { float, float }, ptr %agg.result, i32 0, i32 0 // PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds { float, float }, ptr %agg.result, i32 0, i32 1 // PPC32LNX-NEXT: store float %{{.*}}, ptr [[RETREAL]], align 4 @@ -21,7 +21,7 @@ _Complex double foo2(_Complex double x) { // CHECK-LABEL: define{{.*}} { double, double } @foo2(double noundef %x.{{.*}}, double noundef %x.{{.*}}) #0 { // CHECK: ret { double, double } -// PPC32LNX-LABEL: define{{.*}} void @foo2(ptr noalias sret({ double, double }) align 8 %agg.result, ptr noundef byval({ double, double }) align 8 %x) #0 { +// PPC32LNX-LABEL: define{{.*}} void @foo2(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr noundef byval({ double, double }) align 8 %x) #0 { // PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds { double, double }, ptr %agg.result, i32 0, i32 0 // PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds { double, double }, ptr %agg.result, i32 0, i32 1 // PPC32LNX-NEXT: store double %{{.*}}, ptr [[RETREAL]], align 8 @@ -36,7 +36,7 @@ _Complex long double foo3(_Complex long double x) { // CHECK-LDBL128-LABEL: define{{.*}} { ppc_fp128, ppc_fp128 } @foo3(ppc_fp128 noundef %x.{{.*}}, ppc_fp128 noundef %x.{{.*}}) #0 { // CHECK-LDBL128: ret { ppc_fp128, ppc_fp128 } -// PPC32LNX-LABEL: define{{.*}} void @foo3(ptr noalias sret({ ppc_fp128, ppc_fp128 }) align 16 %agg.result, ptr noundef byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 { +// PPC32LNX-LABEL: define{{.*}} void @foo3(ptr dead_on_unwind noalias writable sret({ ppc_fp128, ppc_fp128 }) align 16 %agg.result, ptr noundef byval({ ppc_fp128, ppc_fp128 }) align 16 %x) #0 { // PPC32LNX: [[RETREAL:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 0 // PPC32LNX-NEXT: [[RETIMAG:%.*]] = getelementptr inbounds { ppc_fp128, ppc_fp128 }, ptr %agg.result, i32 0, i32 1 // PPC32LNX-NEXT: store ppc_fp128 %{{.*}}, ptr [[RETREAL]], align 16 diff --git a/clang/test/CodeGen/PowerPC/ppc-aggregate-abi.cpp b/clang/test/CodeGen/PowerPC/ppc-aggregate-abi.cpp index 0c094891fec50..a7f7f3ee558c3 100644 --- a/clang/test/CodeGen/PowerPC/ppc-aggregate-abi.cpp +++ b/clang/test/CodeGen/PowerPC/ppc-aggregate-abi.cpp @@ -4,57 +4,57 @@ // RUN: -o - %s | FileCheck %s -check-prefix=CHECK-LE class agg_float_class { float a; }; -// CHECK-BE-LABEL: define{{.*}} void @_Z20pass_agg_float_class15agg_float_class(ptr noalias sret(%class.agg_float_class) align 4 %{{.*}}, float inreg %{{.*}}) +// CHECK-BE-LABEL: define{{.*}} void @_Z20pass_agg_float_class15agg_float_class(ptr dead_on_unwind noalias writable sret(%class.agg_float_class) align 4 %{{.*}}, float inreg %{{.*}}) // CHECK-LE-LABEL: define{{.*}} [1 x float] @_Z20pass_agg_float_class15agg_float_class(float inreg %{{.*}}) agg_float_class pass_agg_float_class(agg_float_class arg) { return arg; } class agg_double_class { double a; }; -// CHECK-BE-LABEL: define{{.*}} void @_Z21pass_agg_double_class16agg_double_class(ptr noalias sret(%class.agg_double_class) align 8 %{{.*}}, double inreg %{{.*}}) +// CHECK-BE-LABEL: define{{.*}} void @_Z21pass_agg_double_class16agg_double_class(ptr dead_on_unwind noalias writable sret(%class.agg_double_class) align 8 %{{.*}}, double inreg %{{.*}}) // CHECK-LE-LABEL: define{{.*}} [1 x double] @_Z21pass_agg_double_class16agg_double_class(double inreg %{{.*}}) agg_double_class pass_agg_double_class(agg_double_class arg) { return arg; } struct agg_float_cpp { float a; int : 0; }; -// CHECK-BE-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(ptr noalias sret(%struct.agg_float_cpp) align 4 %{{.*}}, float inreg %{{.*}}) +// CHECK-BE-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(ptr dead_on_unwind noalias writable sret(%struct.agg_float_cpp) align 4 %{{.*}}, float inreg %{{.*}}) // CHECK-LE-LABEL: define{{.*}} [1 x float] @_Z18pass_agg_float_cpp13agg_float_cpp(float inreg %{{.*}}) agg_float_cpp pass_agg_float_cpp(agg_float_cpp arg) { return arg; } struct empty { }; struct agg_nofloat_empty { float a; empty dummy; }; -// CHECK-BE-LABEL: define{{.*}} void @_Z22pass_agg_nofloat_empty17agg_nofloat_empty(ptr noalias sret(%struct.agg_nofloat_empty) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-BE-LABEL: define{{.*}} void @_Z22pass_agg_nofloat_empty17agg_nofloat_empty(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_empty) align 4 %{{.*}}, i64 %{{.*}}) // CHECK-LE-LABEL: define{{.*}} i64 @_Z22pass_agg_nofloat_empty17agg_nofloat_empty(i64 %{{.*}}) agg_nofloat_empty pass_agg_nofloat_empty(agg_nofloat_empty arg) { return arg; } struct agg_float_empty { float a; [[no_unique_address]] empty dummy; }; -// CHECK-BE-LABEL: define{{.*}} void @_Z20pass_agg_float_empty15agg_float_empty(ptr noalias sret(%struct.agg_float_empty) align 4 %{{.*}}, float inreg %{{.*}}) +// CHECK-BE-LABEL: define{{.*}} void @_Z20pass_agg_float_empty15agg_float_empty(ptr dead_on_unwind noalias writable sret(%struct.agg_float_empty) align 4 %{{.*}}, float inreg %{{.*}}) // CHECK-LE-LABEL: define{{.*}} [1 x float] @_Z20pass_agg_float_empty15agg_float_empty(float inreg %{{.*}}) agg_float_empty pass_agg_float_empty(agg_float_empty arg) { return arg; } struct agg_nofloat_emptyarray { float a; [[no_unique_address]] empty dummy[3]; }; -// CHECK-BE-LABEL: define{{.*}} void @_Z27pass_agg_nofloat_emptyarray22agg_nofloat_emptyarray(ptr noalias sret(%struct.agg_nofloat_emptyarray) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-BE-LABEL: define{{.*}} void @_Z27pass_agg_nofloat_emptyarray22agg_nofloat_emptyarray(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_emptyarray) align 4 %{{.*}}, i64 %{{.*}}) // CHECK-LE-LABEL: define{{.*}} i64 @_Z27pass_agg_nofloat_emptyarray22agg_nofloat_emptyarray(i64 %{{.*}}) agg_nofloat_emptyarray pass_agg_nofloat_emptyarray(agg_nofloat_emptyarray arg) { return arg; } struct noemptybase { empty dummy; }; struct agg_nofloat_emptybase : noemptybase { float a; }; -// CHECK-BE-LABEL: define{{.*}} void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(ptr noalias sret(%struct.agg_nofloat_emptybase) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-BE-LABEL: define{{.*}} void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_emptybase) align 4 %{{.*}}, i64 %{{.*}}) // CHECK-LE-LABEL: define{{.*}} i64 @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(i64 %{{.*}}) agg_nofloat_emptybase pass_agg_nofloat_emptybase(agg_nofloat_emptybase arg) { return arg; } struct emptybase { [[no_unique_address]] empty dummy; }; struct agg_float_emptybase : emptybase { float a; }; -// CHECK-BE-LABEL: define{{.*}} void @_Z24pass_agg_float_emptybase19agg_float_emptybase(ptr noalias sret(%struct.agg_float_emptybase) align 4 %{{.*}}, float inreg %{{.*}}) +// CHECK-BE-LABEL: define{{.*}} void @_Z24pass_agg_float_emptybase19agg_float_emptybase(ptr dead_on_unwind noalias writable sret(%struct.agg_float_emptybase) align 4 %{{.*}}, float inreg %{{.*}}) // CHECK-LE-LABEL: define{{.*}} [1 x float] @_Z24pass_agg_float_emptybase19agg_float_emptybase(float inreg %{{.*}}) agg_float_emptybase pass_agg_float_emptybase(agg_float_emptybase arg) { return arg; } struct noemptybasearray { [[no_unique_address]] empty dummy[3]; }; struct agg_nofloat_emptybasearray : noemptybasearray { float a; }; -// CHECK-BE-LABEL: define{{.*}} void @_Z31pass_agg_nofloat_emptybasearray26agg_nofloat_emptybasearray(ptr noalias sret(%struct.agg_nofloat_emptybasearray) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-BE-LABEL: define{{.*}} void @_Z31pass_agg_nofloat_emptybasearray26agg_nofloat_emptybasearray(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_emptybasearray) align 4 %{{.*}}, i64 %{{.*}}) // CHECK-LE-LABEL: define{{.*}} i64 @_Z31pass_agg_nofloat_emptybasearray26agg_nofloat_emptybasearray(i64 %{{.*}}) agg_nofloat_emptybasearray pass_agg_nofloat_emptybasearray(agg_nofloat_emptybasearray arg) { return arg; } -// CHECK-BE: call void @_Z24pass_agg_float_emptybase19agg_float_emptybase(ptr sret(%struct.agg_float_emptybase) align 4 %{{.*}}, float inreg %{{.*}}) +// CHECK-BE: call void @_Z24pass_agg_float_emptybase19agg_float_emptybase(ptr dead_on_unwind writable sret(%struct.agg_float_emptybase) align 4 %{{.*}}, float inreg %{{.*}}) // CHECK-LE: call [1 x float] @_Z24pass_agg_float_emptybase19agg_float_emptybase(float inreg %{{.*}}) void pass_agg_float_emptybase_ptr(agg_float_emptybase* arg) { pass_agg_float_emptybase(*arg); } -// CHECK-BE: call void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(ptr sret(%struct.agg_nofloat_emptybase) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-BE: call void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(ptr dead_on_unwind writable sret(%struct.agg_nofloat_emptybase) align 4 %{{.*}}, i64 %{{.*}}) // CHECK-LE: call i64 @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(i64 %{{.*}}) void pass_agg_nofloat_emptybase_ptr(agg_nofloat_emptybase* arg) { pass_agg_nofloat_emptybase(*arg); } diff --git a/clang/test/CodeGen/PowerPC/ppc32-and-aix-struct-return.c b/clang/test/CodeGen/PowerPC/ppc32-and-aix-struct-return.c index b0bb089d664c2..cfe5c1ca3e851 100644 --- a/clang/test/CodeGen/PowerPC/ppc32-and-aix-struct-return.c +++ b/clang/test/CodeGen/PowerPC/ppc32-and-aix-struct-return.c @@ -59,42 +59,42 @@ typedef struct { char c[9]; } Nine; -// CHECK-AIX-LABEL: define{{.*}} void @ret0(ptr noalias sret(%struct.Zero) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret0(ptr dead_on_unwind noalias writable sret(%struct.Zero) {{[^,]*}}) // CHECK-SVR4-LABEL: define{{.*}} void @ret0() Zero ret0(void) { return (Zero){}; } -// CHECK-AIX-LABEL: define{{.*}} void @ret1(ptr noalias sret(%struct.One) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret1(ptr dead_on_unwind noalias writable sret(%struct.One) {{[^,]*}}) // CHECK-SVR4-LABEL: define{{.*}} i8 @ret1() One ret1(void) { return (One){'a'}; } -// CHECK-AIX-LABEL: define{{.*}} void @ret2(ptr noalias sret(%struct.Two) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret2(ptr dead_on_unwind noalias writable sret(%struct.Two) {{[^,]*}}) // CHECK-SVR4-LABEL: define{{.*}} i16 @ret2() Two ret2(void) { return (Two){123}; } -// CHECK-AIX-LABEL: define{{.*}} void @ret3(ptr noalias sret(%struct.Three) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret3(ptr dead_on_unwind noalias writable sret(%struct.Three) {{[^,]*}}) // CHECK-SVR4-LABEL: define{{.*}} i24 @ret3() Three ret3(void) { return (Three){"abc"}; } -// CHECK-AIX-LABEL: define{{.*}} void @ret4(ptr noalias sret(%struct.Four) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret4(ptr dead_on_unwind noalias writable sret(%struct.Four) {{[^,]*}}) // CHECK-SVR4-LABEL: define{{.*}} i32 @ret4() Four ret4(void) { return (Four){0.4}; } -// CHECK-AIX-LABEL: define{{.*}} void @ret5(ptr noalias sret(%struct.Five) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret5(ptr dead_on_unwind noalias writable sret(%struct.Five) {{[^,]*}}) // CHECK-SVR4-LABEL: define{{.*}} i40 @ret5() Five ret5(void) { return (Five){"abcde"}; } -// CHECK-AIX-LABEL: define{{.*}} void @ret6(ptr noalias sret(%struct.Six) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret6(ptr dead_on_unwind noalias writable sret(%struct.Six) {{[^,]*}}) // CHECK-SVR4-LABEL: define{{.*}} i48 @ret6() Six ret6(void) { return (Six){12, 34, 56}; } -// CHECK-AIX-LABEL: define{{.*}} void @ret7(ptr noalias sret(%struct.Seven) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret7(ptr dead_on_unwind noalias writable sret(%struct.Seven) {{[^,]*}}) // CHECK-SVR4-LABEL: define{{.*}} i56 @ret7() Seven ret7(void) { return (Seven){"abcdefg"}; } -// CHECK-AIX-LABEL: define{{.*}} void @ret8(ptr noalias sret(%struct.Eight) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret8(ptr dead_on_unwind noalias writable sret(%struct.Eight) {{[^,]*}}) // CHECK-SVR4-LABEL: define{{.*}} i64 @ret8() Eight ret8(void) { return (Eight){123, 'a'}; } -// CHECK-AIX-LABEL: define{{.*}} void @ret9(ptr noalias sret(%struct.Nine) {{[^,]*}}) -// CHECK-SVR4-LABEL: define{{.*}} void @ret9(ptr noalias sret(%struct.Nine) {{[^,]*}}) +// CHECK-AIX-LABEL: define{{.*}} void @ret9(ptr dead_on_unwind noalias writable sret(%struct.Nine) {{[^,]*}}) +// CHECK-SVR4-LABEL: define{{.*}} void @ret9(ptr dead_on_unwind noalias writable sret(%struct.Nine) {{[^,]*}}) Nine ret9(void) { return (Nine){"abcdefghi"}; } diff --git a/clang/test/CodeGen/PowerPC/ppc64-align-struct.c b/clang/test/CodeGen/PowerPC/ppc64-align-struct.c index 2476c7149d076..50e8330fceaec 100644 --- a/clang/test/CodeGen/PowerPC/ppc64-align-struct.c +++ b/clang/test/CodeGen/PowerPC/ppc64-align-struct.c @@ -60,7 +60,7 @@ void test9 (int x, struct test9 y) { } -// CHECK: define{{.*}} void @test1va(ptr noalias sret(%struct.test1) align 4 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) +// CHECK: define{{.*}} void @test1va(ptr dead_on_unwind noalias writable sret(%struct.test1) align 4 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) // CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 8 // CHECK: store ptr %[[NEXT]], ptr %ap @@ -75,7 +75,7 @@ struct test1 test1va (int x, ...) return y; } -// CHECK: define{{.*}} void @test2va(ptr noalias sret(%struct.test2) align 16 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) +// CHECK: define{{.*}} void @test2va(ptr dead_on_unwind noalias writable sret(%struct.test2) align 16 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) // CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap // CHECK: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15 // CHECK: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16) @@ -92,7 +92,7 @@ struct test2 test2va (int x, ...) return y; } -// CHECK: define{{.*}} void @test3va(ptr noalias sret(%struct.test3) align 32 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) +// CHECK: define{{.*}} void @test3va(ptr dead_on_unwind noalias writable sret(%struct.test3) align 32 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) // CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap // CHECK: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15 // CHECK: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16) @@ -109,7 +109,7 @@ struct test3 test3va (int x, ...) return y; } -// CHECK: define{{.*}} void @test4va(ptr noalias sret(%struct.test4) align 4 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) +// CHECK: define{{.*}} void @test4va(ptr dead_on_unwind noalias writable sret(%struct.test4) align 4 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) // CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 16 // CHECK: store ptr %[[NEXT]], ptr %ap @@ -124,7 +124,7 @@ struct test4 test4va (int x, ...) return y; } -// CHECK: define{{.*}} void @test8va(ptr noalias sret(%struct.test8) align 1 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) +// CHECK: define{{.*}} void @test8va(ptr dead_on_unwind noalias writable sret(%struct.test8) align 1 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) // CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 8 // CHECK: store ptr %[[NEXT]], ptr %ap @@ -140,7 +140,7 @@ struct test8 test8va (int x, ...) return y; } -// CHECK: define{{.*}} void @test9va(ptr noalias sret(%struct.test9) align 1 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) +// CHECK: define{{.*}} void @test9va(ptr dead_on_unwind noalias writable sret(%struct.test9) align 1 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) // CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 8 // CHECK: store ptr %[[NEXT]], ptr %ap @@ -156,7 +156,7 @@ struct test9 test9va (int x, ...) return y; } -// CHECK: define{{.*}} void @testva_longdouble(ptr noalias sret(%struct.test_longdouble) align 16 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) +// CHECK: define{{.*}} void @testva_longdouble(ptr dead_on_unwind noalias writable sret(%struct.test_longdouble) align 16 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) // CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap // CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i64 16 // CHECK: store ptr %[[NEXT]], ptr %ap @@ -172,7 +172,7 @@ struct test_longdouble testva_longdouble (int x, ...) return y; } -// CHECK: define{{.*}} void @testva_vector(ptr noalias sret(%struct.test_vector) align 16 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) +// CHECK: define{{.*}} void @testva_vector(ptr dead_on_unwind noalias writable sret(%struct.test_vector) align 16 %[[AGG_RESULT:.*]], i32 noundef signext %x, ...) // CHECK: %[[CUR:[^ ]+]] = load ptr, ptr %ap // CHECK: %[[TMP0:[^ ]+]] = getelementptr inbounds i8, ptr %[[CUR]], i32 15 // CHECK: %[[ALIGN:[^ ]+]] = call ptr @llvm.ptrmask.p0.i64(ptr %[[TMP0]], i64 -16) diff --git a/clang/test/CodeGen/PowerPC/ppc64-elf-abi.c b/clang/test/CodeGen/PowerPC/ppc64-elf-abi.c index 64bff635af953..fa7f79455fda4 100644 --- a/clang/test/CodeGen/PowerPC/ppc64-elf-abi.c +++ b/clang/test/CodeGen/PowerPC/ppc64-elf-abi.c @@ -15,7 +15,7 @@ // RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s \ // RUN: -target-abi elfv2 | FileCheck %s --check-prefix=CHECK-ELFv2 -// CHECK-ELFv1: define{{.*}} void @func_fab(ptr noalias sret(%struct.fab) align 4 %agg.result, i64 %x.coerce) +// CHECK-ELFv1: define{{.*}} void @func_fab(ptr dead_on_unwind noalias writable sret(%struct.fab) align 4 %agg.result, i64 %x.coerce) // CHECK-ELFv2: define{{.*}} [2 x float] @func_fab([2 x float] %x.coerce) struct fab { float a; float b; }; struct fab func_fab(struct fab x) { return x; } diff --git a/clang/test/CodeGen/PowerPC/ppc64-soft-float.c b/clang/test/CodeGen/PowerPC/ppc64-soft-float.c index c2e887ef7ab6e..812d9ff5a3509 100644 --- a/clang/test/CodeGen/PowerPC/ppc64-soft-float.c +++ b/clang/test/CodeGen/PowerPC/ppc64-soft-float.c @@ -30,53 +30,53 @@ struct fabc { float a; float b; float c; }; struct f2a2b { float a[2]; float b[2]; }; // CHECK-LE: define{{.*}} i32 @func_f1(float inreg %x.coerce) -// CHECK-BE: define{{.*}} void @func_f1(ptr noalias sret(%struct.f1) align 4 %agg.result, float inreg %x.coerce) +// CHECK-BE: define{{.*}} void @func_f1(ptr dead_on_unwind noalias writable sret(%struct.f1) align 4 %agg.result, float inreg %x.coerce) struct f1 func_f1(struct f1 x) { return x; } // CHECK-LE: define{{.*}} i64 @func_f2(i64 %x.coerce) -// CHECK-BE: define{{.*}} void @func_f2(ptr noalias sret(%struct.f2) align 4 %agg.result, i64 %x.coerce) +// CHECK-BE: define{{.*}} void @func_f2(ptr dead_on_unwind noalias writable sret(%struct.f2) align 4 %agg.result, i64 %x.coerce) struct f2 func_f2(struct f2 x) { return x; } // CHECK-LE: define{{.*}} { i64, i64 } @func_f3([2 x i64] %x.coerce) -// CHECK-BE: define{{.*}} void @func_f3(ptr noalias sret(%struct.f3) align 4 %agg.result, [2 x i64] %x.coerce) +// CHECK-BE: define{{.*}} void @func_f3(ptr dead_on_unwind noalias writable sret(%struct.f3) align 4 %agg.result, [2 x i64] %x.coerce) struct f3 func_f3(struct f3 x) { return x; } // CHECK-LE: define{{.*}} { i64, i64 } @func_f4([2 x i64] %x.coerce) -// CHECK-BE: define{{.*}} void @func_f4(ptr noalias sret(%struct.f4) align 4 %agg.result, [2 x i64] %x.coerce) +// CHECK-BE: define{{.*}} void @func_f4(ptr dead_on_unwind noalias writable sret(%struct.f4) align 4 %agg.result, [2 x i64] %x.coerce) struct f4 func_f4(struct f4 x) { return x; } -// CHECK: define{{.*}} void @func_f5(ptr noalias sret(%struct.f5) align 4 %agg.result, [3 x i64] %x.coerce) +// CHECK: define{{.*}} void @func_f5(ptr dead_on_unwind noalias writable sret(%struct.f5) align 4 %agg.result, [3 x i64] %x.coerce) struct f5 func_f5(struct f5 x) { return x; } -// CHECK: define{{.*}} void @func_f6(ptr noalias sret(%struct.f6) align 4 %agg.result, [3 x i64] %x.coerce) +// CHECK: define{{.*}} void @func_f6(ptr dead_on_unwind noalias writable sret(%struct.f6) align 4 %agg.result, [3 x i64] %x.coerce) struct f6 func_f6(struct f6 x) { return x; } -// CHECK: define{{.*}} void @func_f7(ptr noalias sret(%struct.f7) align 4 %agg.result, [4 x i64] %x.coerce) +// CHECK: define{{.*}} void @func_f7(ptr dead_on_unwind noalias writable sret(%struct.f7) align 4 %agg.result, [4 x i64] %x.coerce) struct f7 func_f7(struct f7 x) { return x; } -// CHECK: define{{.*}} void @func_f8(ptr noalias sret(%struct.f8) align 4 %agg.result, [4 x i64] %x.coerce) +// CHECK: define{{.*}} void @func_f8(ptr dead_on_unwind noalias writable sret(%struct.f8) align 4 %agg.result, [4 x i64] %x.coerce) struct f8 func_f8(struct f8 x) { return x; } -// CHECK: define{{.*}} void @func_f9(ptr noalias sret(%struct.f9) align 4 %agg.result, [5 x i64] %x.coerce) +// CHECK: define{{.*}} void @func_f9(ptr dead_on_unwind noalias writable sret(%struct.f9) align 4 %agg.result, [5 x i64] %x.coerce) struct f9 func_f9(struct f9 x) { return x; } // CHECK-LE: define{{.*}} i64 @func_fab(i64 %x.coerce) -// CHECK-BE: define{{.*}} void @func_fab(ptr noalias sret(%struct.fab) align 4 %agg.result, i64 %x.coerce) +// CHECK-BE: define{{.*}} void @func_fab(ptr dead_on_unwind noalias writable sret(%struct.fab) align 4 %agg.result, i64 %x.coerce) struct fab func_fab(struct fab x) { return x; } // CHECK-LE: define{{.*}} { i64, i64 } @func_fabc([2 x i64] %x.coerce) -// CHECK-BE: define{{.*}} void @func_fabc(ptr noalias sret(%struct.fabc) align 4 %agg.result, [2 x i64] %x.coerce) +// CHECK-BE: define{{.*}} void @func_fabc(ptr dead_on_unwind noalias writable sret(%struct.fabc) align 4 %agg.result, [2 x i64] %x.coerce) struct fabc func_fabc(struct fabc x) { return x; } // CHECK-LE: define{{.*}} { i64, i64 } @func_f2a2b([2 x i64] %x.coerce) -// CHECK-BE: define{{.*}} void @func_f2a2b(ptr noalias sret(%struct.f2a2b) align 4 %agg.result, [2 x i64] %x.coerce) +// CHECK-BE: define{{.*}} void @func_f2a2b(ptr dead_on_unwind noalias writable sret(%struct.f2a2b) align 4 %agg.result, [2 x i64] %x.coerce) struct f2a2b func_f2a2b(struct f2a2b x) { return x; } // CHECK-LABEL: @call_f1 // CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f1, align 4 // CHECK: %[[TMP:[^ ]+]] = load float, ptr @global_f1, align 4 // CHECK-LE: call i32 @func_f1(float inreg %[[TMP]]) -// CHECK-BE: call void @func_f1(ptr sret(%struct.f1) align 4 %[[TMP0]], float inreg %[[TMP]]) +// CHECK-BE: call void @func_f1(ptr dead_on_unwind writable sret(%struct.f1) align 4 %[[TMP0]], float inreg %[[TMP]]) struct f1 global_f1; void call_f1(void) { global_f1 = func_f1(global_f1); } @@ -84,7 +84,7 @@ void call_f1(void) { global_f1 = func_f1(global_f1); } // CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f2, align 4 // CHECK: %[[TMP:[^ ]+]] = load i64, ptr @global_f2, align 4 // CHECK-LE: call i64 @func_f2(i64 %[[TMP]]) -// CHECK-BE: call void @func_f2(ptr sret(%struct.f2) align 4 %[[TMP0]], i64 %[[TMP]]) +// CHECK-BE: call void @func_f2(ptr dead_on_unwind writable sret(%struct.f2) align 4 %[[TMP0]], i64 %[[TMP]]) struct f2 global_f2; void call_f2(void) { global_f2 = func_f2(global_f2); } @@ -94,7 +94,7 @@ void call_f2(void) { global_f2 = func_f2(global_f2); } // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP1]], ptr align 4 @global_f3, i64 12, i1 false) // CHECK: %[[TMP3:[^ ]+]] = load [2 x i64], ptr %[[TMP1]] // CHECK-LE: call { i64, i64 } @func_f3([2 x i64] %[[TMP3]]) -// CHECK-BE: call void @func_f3(ptr sret(%struct.f3) align 4 %[[TMP0]], [2 x i64] %[[TMP3]]) +// CHECK-BE: call void @func_f3(ptr dead_on_unwind writable sret(%struct.f3) align 4 %[[TMP0]], [2 x i64] %[[TMP3]]) struct f3 global_f3; void call_f3(void) { global_f3 = func_f3(global_f3); } @@ -102,7 +102,7 @@ void call_f3(void) { global_f3 = func_f3(global_f3); } // CHECK-BE: %[[TMP0:[^ ]+]] = alloca %struct.f4, align 4 // CHECK: %[[TMP:[^ ]+]] = load [2 x i64], ptr @global_f4, align 4 // CHECK-LE: call { i64, i64 } @func_f4([2 x i64] %[[TMP]]) -// CHECK-BE: call void @func_f4(ptr sret(%struct.f4) align 4 %[[TMP0]], [2 x i64] %[[TMP]]) +// CHECK-BE: call void @func_f4(ptr dead_on_unwind writable sret(%struct.f4) align 4 %[[TMP0]], [2 x i64] %[[TMP]]) struct f4 global_f4; void call_f4(void) { global_f4 = func_f4(global_f4); } @@ -111,14 +111,14 @@ void call_f4(void) { global_f4 = func_f4(global_f4); } // CHECK: %[[TMP1:[^ ]+]] = alloca [3 x i64] // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP1]], ptr align 4 @global_f5, i64 20, i1 false) // CHECK: %[[TMP3:[^ ]+]] = load [3 x i64], ptr %[[TMP1]] -// CHECK: call void @func_f5(ptr sret(%struct.f5) align 4 %[[TMP0]], [3 x i64] %[[TMP3]]) +// CHECK: call void @func_f5(ptr dead_on_unwind writable sret(%struct.f5) align 4 %[[TMP0]], [3 x i64] %[[TMP3]]) struct f5 global_f5; void call_f5(void) { global_f5 = func_f5(global_f5); } // CHECK-LABEL: @call_f6 // CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f6, align 4 // CHECK: %[[TMP:[^ ]+]] = load [3 x i64], ptr @global_f6, align 4 -// CHECK: call void @func_f6(ptr sret(%struct.f6) align 4 %[[TMP0]], [3 x i64] %[[TMP]]) +// CHECK: call void @func_f6(ptr dead_on_unwind writable sret(%struct.f6) align 4 %[[TMP0]], [3 x i64] %[[TMP]]) struct f6 global_f6; void call_f6(void) { global_f6 = func_f6(global_f6); } @@ -127,14 +127,14 @@ void call_f6(void) { global_f6 = func_f6(global_f6); } // CHECK: %[[TMP1:[^ ]+]] = alloca [4 x i64], align 8 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP1]], ptr align 4 @global_f7, i64 28, i1 false) // CHECK: %[[TMP3:[^ ]+]] = load [4 x i64], ptr %[[TMP1]], align 8 -// CHECK: call void @func_f7(ptr sret(%struct.f7) align 4 %[[TMP0]], [4 x i64] %[[TMP3]]) +// CHECK: call void @func_f7(ptr dead_on_unwind writable sret(%struct.f7) align 4 %[[TMP0]], [4 x i64] %[[TMP3]]) struct f7 global_f7; void call_f7(void) { global_f7 = func_f7(global_f7); } // CHECK-LABEL: @call_f8 // CHECK: %[[TMP0:[^ ]+]] = alloca %struct.f8, align 4 // CHECK: %[[TMP:[^ ]+]] = load [4 x i64], ptr @global_f8, align 4 -// CHECK: call void @func_f8(ptr sret(%struct.f8) align 4 %[[TMP0]], [4 x i64] %[[TMP]]) +// CHECK: call void @func_f8(ptr dead_on_unwind writable sret(%struct.f8) align 4 %[[TMP0]], [4 x i64] %[[TMP]]) struct f8 global_f8; void call_f8(void) { global_f8 = func_f8(global_f8); } @@ -142,7 +142,7 @@ void call_f8(void) { global_f8 = func_f8(global_f8); } // CHECK: %[[TMP1:[^ ]+]] = alloca [5 x i64] // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP1]], ptr align 4 @global_f9, i64 36, i1 false) // CHECK: %[[TMP3:[^ ]+]] = load [5 x i64], ptr %[[TMP1]] -// CHECK: call void @func_f9(ptr sret(%struct.f9) align 4 %{{[^ ]+}}, [5 x i64] %[[TMP3]]) +// CHECK: call void @func_f9(ptr dead_on_unwind writable sret(%struct.f9) align 4 %{{[^ ]+}}, [5 x i64] %[[TMP3]]) struct f9 global_f9; void call_f9(void) { global_f9 = func_f9(global_f9); } @@ -150,7 +150,7 @@ void call_f9(void) { global_f9 = func_f9(global_f9); } // CHECK: %[[TMP0:[^ ]+]] = alloca %struct.fab, align 4 // CHECK: %[[TMP:[^ ]+]] = load i64, ptr @global_fab, align 4 // CHECK-LE: %call = call i64 @func_fab(i64 %[[TMP]]) -// CHECK-BE: call void @func_fab(ptr sret(%struct.fab) align 4 %[[TMP0]], i64 %[[TMP]]) +// CHECK-BE: call void @func_fab(ptr dead_on_unwind writable sret(%struct.fab) align 4 %[[TMP0]], i64 %[[TMP]]) struct fab global_fab; void call_fab(void) { global_fab = func_fab(global_fab); } @@ -160,7 +160,7 @@ void call_fab(void) { global_fab = func_fab(global_fab); } // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP0]], ptr align 4 @global_fabc, i64 12, i1 false) // CHECK: %[[TMP3:[^ ]+]] = load [2 x i64], ptr %[[TMP0]], align 8 // CHECK-LE: %call = call { i64, i64 } @func_fabc([2 x i64] %[[TMP3]]) -// CHECK-BE: call void @func_fabc(ptr sret(%struct.fabc) align 4 %[[TMPX]], [2 x i64] %[[TMP3]]) +// CHECK-BE: call void @func_fabc(ptr dead_on_unwind writable sret(%struct.fabc) align 4 %[[TMPX]], [2 x i64] %[[TMP3]]) struct fabc global_fabc; void call_fabc(void) { global_fabc = func_fabc(global_fabc); } diff --git a/clang/test/CodeGen/PowerPC/ppc64-vector.c b/clang/test/CodeGen/PowerPC/ppc64-vector.c index 2e685799efa07..5d3dd86a009d5 100644 --- a/clang/test/CodeGen/PowerPC/ppc64-vector.c +++ b/clang/test/CodeGen/PowerPC/ppc64-vector.c @@ -39,13 +39,13 @@ v8i16 test_v8i16(v8i16 x) return x; } -// CHECK: define{{.*}} void @test_v16i16(ptr noalias sret(<16 x i16>) align 32 %agg.result, ptr noundef %0) +// CHECK: define{{.*}} void @test_v16i16(ptr dead_on_unwind noalias writable sret(<16 x i16>) align 32 %agg.result, ptr noundef %0) v16i16 test_v16i16(v16i16 x) { return x; } -// CHECK: define{{.*}} void @test_struct_v16i16(ptr noalias sret(%struct.v16i16) align 32 %agg.result, [2 x i128] %x.coerce) +// CHECK: define{{.*}} void @test_struct_v16i16(ptr dead_on_unwind noalias writable sret(%struct.v16i16) align 32 %agg.result, [2 x i128] %x.coerce) struct v16i16 test_struct_v16i16(struct v16i16 x) { return x; diff --git a/clang/test/CodeGen/PowerPC/ppc64le-aggregates.c b/clang/test/CodeGen/PowerPC/ppc64le-aggregates.c index 42b179217dd2e..3ea85a6a8ff3b 100644 --- a/clang/test/CodeGen/PowerPC/ppc64le-aggregates.c +++ b/clang/test/CodeGen/PowerPC/ppc64le-aggregates.c @@ -41,7 +41,7 @@ struct f7 func_f7(struct f7 x) { return x; } // CHECK: define{{.*}} [8 x float] @func_f8([8 x float] %x.coerce) struct f8 func_f8(struct f8 x) { return x; } -// CHECK: define{{.*}} void @func_f9(ptr noalias sret(%struct.f9) align 4 %agg.result, [5 x i64] %x.coerce) +// CHECK: define{{.*}} void @func_f9(ptr dead_on_unwind noalias writable sret(%struct.f9) align 4 %agg.result, [5 x i64] %x.coerce) struct f9 func_f9(struct f9 x) { return x; } // CHECK: define{{.*}} [2 x float] @func_fab([2 x float] %x.coerce) @@ -105,7 +105,7 @@ void call_f8(void) { global_f8 = func_f8(global_f8); } // CHECK: %[[TMP1:[^ ]+]] = alloca [5 x i64] // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[TMP1]], ptr align 4 @global_f9, i64 36, i1 false) // CHECK: %[[TMP3:[^ ]+]] = load [5 x i64], ptr %[[TMP1]] -// CHECK: call void @func_f9(ptr sret(%struct.f9) align 4 %{{[^ ]+}}, [5 x i64] %[[TMP3]]) +// CHECK: call void @func_f9(ptr dead_on_unwind writable sret(%struct.f9) align 4 %{{[^ ]+}}, [5 x i64] %[[TMP3]]) struct f9 global_f9; void call_f9(void) { global_f9 = func_f9(global_f9); } @@ -161,7 +161,7 @@ struct v7 func_v7(struct v7 x) { return x; } // CHECK: define{{.*}} [8 x <4 x i32>] @func_v8([8 x <4 x i32>] %x.coerce) struct v8 func_v8(struct v8 x) { return x; } -// CHECK: define{{.*}} void @func_v9(ptr noalias sret(%struct.v9) align 16 %agg.result, ptr noundef byval(%struct.v9) align 16 %x) +// CHECK: define{{.*}} void @func_v9(ptr dead_on_unwind noalias writable sret(%struct.v9) align 16 %agg.result, ptr noundef byval(%struct.v9) align 16 %x) struct v9 func_v9(struct v9 x) { return x; } // CHECK: define{{.*}} [2 x <4 x i32>] @func_vab([2 x <4 x i32>] %x.coerce) @@ -219,7 +219,7 @@ struct v8 global_v8; void call_v8(void) { global_v8 = func_v8(global_v8); } // CHECK-LABEL: @call_v9 -// CHECK: call void @func_v9(ptr sret(%struct.v9) align 16 %{{[^ ]+}}, ptr noundef byval(%struct.v9) align 16 @global_v9) +// CHECK: call void @func_v9(ptr dead_on_unwind writable sret(%struct.v9) align 16 %{{[^ ]+}}, ptr noundef byval(%struct.v9) align 16 @global_v9) struct v9 global_v9; void call_v9(void) { global_v9 = func_v9(global_v9); } @@ -278,7 +278,7 @@ struct v3f7 func_v3f7(struct v3f7 x) { return x; } // CHECK: define{{.*}} [8 x <4 x float>] @func_v3f8([8 x <4 x float>] %x.coerce) struct v3f8 func_v3f8(struct v3f8 x) { return x; } -// CHECK: define{{.*}} void @func_v3f9(ptr noalias sret(%struct.v3f9) align 16 %agg.result, ptr noundef byval(%struct.v3f9) align 16 %x) +// CHECK: define{{.*}} void @func_v3f9(ptr dead_on_unwind noalias writable sret(%struct.v3f9) align 16 %agg.result, ptr noundef byval(%struct.v3f9) align 16 %x) struct v3f9 func_v3f9(struct v3f9 x) { return x; } // CHECK: define{{.*}} [2 x <4 x float>] @func_v3fab([2 x <4 x float>] %x.coerce) @@ -336,7 +336,7 @@ struct v3f8 global_v3f8; void call_v3f8(void) { global_v3f8 = func_v3f8(global_v3f8); } // CHECK-LABEL: @call_v3f9 -// CHECK: call void @func_v3f9(ptr sret(%struct.v3f9) align 16 %{{[^ ]+}}, ptr noundef byval(%struct.v3f9) align 16 @global_v3f9) +// CHECK: call void @func_v3f9(ptr dead_on_unwind writable sret(%struct.v3f9) align 16 %{{[^ ]+}}, ptr noundef byval(%struct.v3f9) align 16 @global_v3f9) struct v3f9 global_v3f9; void call_v3f9(void) { global_v3f9 = func_v3f9(global_v3f9); } diff --git a/clang/test/CodeGen/PowerPC/ppc64le-f128Aggregates.c b/clang/test/CodeGen/PowerPC/ppc64le-f128Aggregates.c index 27c3b14f0a04b..b2e79d6be9b87 100644 --- a/clang/test/CodeGen/PowerPC/ppc64le-f128Aggregates.c +++ b/clang/test/CodeGen/PowerPC/ppc64le-f128Aggregates.c @@ -42,7 +42,7 @@ struct fp7 func_f7(struct fp7 x) { return x; } // CHECK: define{{.*}} [8 x fp128] @func_f8([8 x fp128] %x.coerce) struct fp8 func_f8(struct fp8 x) { return x; } -// CHECK: define{{.*}} void @func_f9(ptr noalias sret(%struct.fp9) align 16 %agg.result, ptr noundef byval(%struct.fp9) align 16 %x) +// CHECK: define{{.*}} void @func_f9(ptr dead_on_unwind noalias writable sret(%struct.fp9) align 16 %agg.result, ptr noundef byval(%struct.fp9) align 16 %x) struct fp9 func_f9(struct fp9 x) { return x; } // CHECK: define{{.*}} [2 x fp128] @func_fab([2 x fp128] %x.coerce) @@ -104,7 +104,7 @@ void call_fp8(void) { global_f8 = func_f8(global_f8); } // CHECK-LABEL: @call_fp9 // CHECK: %[[TMP1:[^ ]+]] = alloca %struct.fp9, align 16 -// CHECK: call void @func_f9(ptr sret(%struct.fp9) align 16 %[[TMP2:[^ ]+]], ptr noundef byval(%struct.fp9) align 16 @global_f9 +// CHECK: call void @func_f9(ptr dead_on_unwind writable sret(%struct.fp9) align 16 %[[TMP2:[^ ]+]], ptr noundef byval(%struct.fp9) align 16 @global_f9 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 16 @global_f9, ptr align 16 %[[TMP2]], i64 144, i1 false // CHECK: ret void struct fp9 global_f9; diff --git a/clang/test/CodeGen/RISCV/bfloat-abi.c b/clang/test/CodeGen/RISCV/bfloat-abi.c index bfaf1043133b8..f38646c8b12ff 100644 --- a/clang/test/CodeGen/RISCV/bfloat-abi.c +++ b/clang/test/CodeGen/RISCV/bfloat-abi.c @@ -467,7 +467,7 @@ struct floatbfloat3 { // CHECK-RV64-NEXT: ret [2 x i64] [[TMP4]] // // CHECK-RV32-LABEL: define dso_local void @fh3 -// CHECK-RV32-SAME: (ptr noalias sret([[STRUCT_FLOATBFLOAT3:%.*]]) align 4 [[AGG_RESULT:%.*]], float noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]]) #[[ATTR0]] { +// CHECK-RV32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_FLOATBFLOAT3:%.*]]) align 4 [[AGG_RESULT:%.*]], float noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]]) #[[ATTR0]] { // CHECK-RV32-NEXT: entry: // CHECK-RV32-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 // CHECK-RV32-NEXT: [[A_ADDR:%.*]] = alloca float, align 4 @@ -545,7 +545,7 @@ struct bfloat5 { // CHECK-RV64-NEXT: ret [2 x i64] [[TMP5]] // // CHECK-RV32-LABEL: define dso_local void @h5 -// CHECK-RV32-SAME: (ptr noalias sret([[STRUCT_BFLOAT5:%.*]]) align 2 [[AGG_RESULT:%.*]], bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]], bfloat noundef [[E:%.*]]) #[[ATTR0]] { +// CHECK-RV32-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_BFLOAT5:%.*]]) align 2 [[AGG_RESULT:%.*]], bfloat noundef [[A:%.*]], bfloat noundef [[B:%.*]], bfloat noundef [[C:%.*]], bfloat noundef [[D:%.*]], bfloat noundef [[E:%.*]]) #[[ATTR0]] { // CHECK-RV32-NEXT: entry: // CHECK-RV32-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 // CHECK-RV32-NEXT: [[A_ADDR:%.*]] = alloca bfloat, align 2 diff --git a/clang/test/CodeGen/RISCV/riscv-abi.cpp b/clang/test/CodeGen/RISCV/riscv-abi.cpp index aa18afe41f6db..fe1a2b6d8595c 100644 --- a/clang/test/CodeGen/RISCV/riscv-abi.cpp +++ b/clang/test/CodeGen/RISCV/riscv-abi.cpp @@ -75,7 +75,7 @@ struct child3_int64_s : parent3_float_s { }; // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @_Z30float_int64_struct_inheritance14child3_int64_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_CHILD3_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD3_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // // LP64-LABEL: define dso_local [2 x i64] @_Z30float_int64_struct_inheritance14child3_int64_s @@ -99,7 +99,7 @@ struct child4_double_s : parent4_double_s { }; // ILP32-ILP32F-LABEL: define dso_local void @_Z32double_double_struct_inheritance15child4_double_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_CHILD4_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD4_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @_Z32double_double_struct_inheritance15child4_double_s @@ -130,11 +130,11 @@ struct child5_virtual_s : virtual parent5_virtual_s { }; // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @_Z38int32_float_virtual_struct_inheritance16child5_virtual_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // // LP64-LP64F-LP64D-LABEL: define dso_local void @_Z38int32_float_virtual_struct_inheritance16child5_virtual_s -// LP64-LP64F-LP64D-SAME: (ptr noalias sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHILD5_VIRTUAL_S:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[A:%.*]]) #[[ATTR0]] { // LP64-LP64F-LP64D: entry: // struct child5_virtual_s int32_float_virtual_struct_inheritance(struct child5_virtual_s a) { diff --git a/clang/test/CodeGen/RISCV/riscv32-abi.c b/clang/test/CodeGen/RISCV/riscv32-abi.c index 040ae500fc60e..ea1bb3b62ee6f 100644 --- a/clang/test/CodeGen/RISCV/riscv32-abi.c +++ b/clang/test/CodeGen/RISCV/riscv32-abi.c @@ -254,7 +254,7 @@ void f_agg_large(struct large x) { // The address where the struct should be written to will be the first // argument // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_agg_large_ret -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 4 [[AGG_RESULT:%.*]], i32 noundef [[I:%.*]], i8 noundef signext [[J:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 4 [[AGG_RESULT:%.*]], i32 noundef [[I:%.*]], i8 noundef signext [[J:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct large f_agg_large_ret(int32_t i, int8_t j) { @@ -272,7 +272,7 @@ void f_vec_large_v16i8(v16i8 x) { } // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_vec_large_v16i8_ret -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret(<16 x i8>) align 16 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret(<16 x i8>) align 16 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // v16i8 f_vec_large_v16i8_ret(void) { @@ -292,7 +292,7 @@ int f_scalar_stack_1(struct tiny a, struct small b, struct small_aligned c, } // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_scalar_stack_2 -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 4 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i64 noundef [[B:%.*]], i64 noundef [[C:%.*]], fp128 noundef [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 4 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i64 noundef [[B:%.*]], i64 noundef [[C:%.*]], fp128 noundef [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct large f_scalar_stack_2(int32_t a, int64_t b, int64_t c, long double d, @@ -329,7 +329,7 @@ int f_scalar_stack_5(int32_t a, int64_t b, float c, double d, long double e, } // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_scalar_stack_6 -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 4 [[AGG_RESULT:%.*]], float noundef [[A:%.*]], i64 noundef [[B:%.*]], double noundef [[C:%.*]], fp128 noundef [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 4 [[AGG_RESULT:%.*]], float noundef [[A:%.*]], i64 noundef [[B:%.*]], double noundef [[C:%.*]], fp128 noundef [[D:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct large f_scalar_stack_6(float a, int64_t b, double c, long double d, @@ -374,7 +374,7 @@ struct int_double_s { int a; double b; }; void f_int_double_s_arg(struct int_double_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_int_double_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_INT_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_INT_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { i32, double } @f_ret_int_double_s @@ -490,7 +490,7 @@ struct double_float_s { double f; float g; }; void f_double_double_s_arg(struct double_double_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_double_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLE_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_double_double_s @@ -512,7 +512,7 @@ struct double_double_s f_ret_double_double_s(void) { void f_double_float_s_arg(struct double_float_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_float_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLE_FLOAT_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_FLOAT_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, float } @f_ret_double_float_s @@ -547,7 +547,7 @@ struct double_int8_zbf_s { double d; int8_t i; int : 0; }; void f_double_int8_s_arg(struct double_int8_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_double_int8_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_DOUBLE_INT8_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_INT8_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct double_int8_s f_ret_double_int8_s(void) { @@ -565,7 +565,7 @@ struct double_int8_s f_ret_double_int8_s(void) { void f_double_uint8_s_arg(struct double_uint8_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_uint8_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLE_UINT8_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_UINT8_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, i8 } @f_ret_double_uint8_s @@ -587,7 +587,7 @@ struct double_uint8_s f_ret_double_uint8_s(void) { void f_double_int32_s_arg(struct double_int32_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_int32_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLE_INT32_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_INT32_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, i32 } @f_ret_double_int32_s @@ -605,7 +605,7 @@ struct double_int32_s f_ret_double_int32_s(void) { void f_double_int64_s_arg(struct double_int64_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_double_int64_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_DOUBLE_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct double_int64_s f_ret_double_int64_s(void) { @@ -623,7 +623,7 @@ struct double_int64_s f_ret_double_int64_s(void) { void f_double_int64bf_s_arg(struct double_int64bf_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_int64bf_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLE_INT64BF_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_INT64BF_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, i32 } @f_ret_double_int64bf_s @@ -648,7 +648,7 @@ struct double_int64bf_s f_ret_double_int64bf_s(void) { void f_double_int8_zbf_s(struct double_int8_zbf_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_int8_zbf_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLE_INT8_ZBF_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_INT8_ZBF_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, i8 } @f_ret_double_int8_zbf_s @@ -687,7 +687,7 @@ void f_struct_double_int8_insufficient_fprs(float a, double b, double c, double void f_doublecomplex(double __complex__ a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_doublecomplex -// ILP32-ILP32F-SAME: (ptr noalias sret({ double, double }) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_doublecomplex @@ -711,7 +711,7 @@ struct doublecomplex_s { double __complex__ c; }; void f_doublecomplex_s_arg(struct doublecomplex_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_doublecomplex_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLECOMPLEX_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLECOMPLEX_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_doublecomplex_s @@ -762,7 +762,7 @@ struct doublearr2_s { double a[2]; }; void f_doublearr2_s_arg(struct doublearr2_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_doublearr2_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLEARR2_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLEARR2_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_doublearr2_s @@ -786,7 +786,7 @@ struct doublearr2_tricky1_s { struct { double f[1]; } g[2]; }; void f_doublearr2_tricky1_s_arg(struct doublearr2_tricky1_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_doublearr2_tricky1_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLEARR2_TRICKY1_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLEARR2_TRICKY1_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_doublearr2_tricky1_s @@ -810,7 +810,7 @@ struct doublearr2_tricky2_s { struct {}; struct { double f[1]; } g[2]; }; void f_doublearr2_tricky2_s_arg(struct doublearr2_tricky2_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_doublearr2_tricky2_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLEARR2_TRICKY2_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLEARR2_TRICKY2_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_doublearr2_tricky2_s @@ -834,7 +834,7 @@ struct doublearr2_tricky3_s { union {}; struct { double f[1]; } g[2]; }; void f_doublearr2_tricky3_s_arg(struct doublearr2_tricky3_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_doublearr2_tricky3_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLEARR2_TRICKY3_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLEARR2_TRICKY3_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_doublearr2_tricky3_s @@ -858,7 +858,7 @@ struct doublearr2_tricky4_s { union {}; struct { struct {}; double f[1]; } g[2]; void f_doublearr2_tricky4_s_arg(struct doublearr2_tricky4_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_doublearr2_tricky4_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLEARR2_TRICKY4_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLEARR2_TRICKY4_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_doublearr2_tricky4_s @@ -881,7 +881,7 @@ struct int_double_int_s { int a; double b; int c; }; void f_int_double_int_s_arg(struct int_double_int_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_int_double_int_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_INT_DOUBLE_INT_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_INT_DOUBLE_INT_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct int_double_int_s f_ret_int_double_int_s(void) { @@ -897,7 +897,7 @@ struct int64_double_s { int64_t a; double b; }; void f_int64_double_s_arg(struct int64_double_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_int64_double_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_INT64_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_INT64_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct int64_double_s f_ret_int64_double_s(void) { @@ -913,7 +913,7 @@ struct char_char_double_s { char a; char b; double c; }; void f_char_char_double_s_arg(struct char_char_double_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_char_char_double_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_CHAR_CHAR_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_CHAR_CHAR_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct char_char_double_s f_ret_char_char_double_s(void) { @@ -946,7 +946,7 @@ union double_u f_ret_double_u(void) { // double+double structs by the ABI. // ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLE_INT32_S:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr noundef [[H:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_INT32_S:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr noundef [[H:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, i32 } @f_ret_double_int32_s_double_int32_s_just_sufficient_gprs @@ -959,7 +959,7 @@ struct double_int32_s f_ret_double_int32_s_double_int32_s_just_sufficient_gprs( } // ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_double_s_double_int32_s_just_sufficient_gprs -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLE_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr noundef [[H:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_DOUBLE_S:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr noundef [[H:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_double_double_s_double_int32_s_just_sufficient_gprs @@ -972,7 +972,7 @@ struct double_double_s f_ret_double_double_s_double_int32_s_just_sufficient_gprs } // ILP32-ILP32F-LABEL: define dso_local void @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs -// ILP32-ILP32F-SAME: (ptr noalias sret({ double, double }) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr noundef [[H:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret({ double, double }) align 8 [[AGG_RESULT:%.*]], i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]], i32 noundef [[D:%.*]], i32 noundef [[E:%.*]], i32 noundef [[F:%.*]], i32 noundef [[G:%.*]], ptr noundef [[H:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, double } @f_ret_doublecomplex_double_int32_s_just_sufficient_gprs @@ -1193,7 +1193,7 @@ struct float_int32_s f_ret_float_int32_s(void) { void f_float_int64_s_arg(struct float_int64_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_float_int64_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_FLOAT_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_FLOAT_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct float_int64_s f_ret_float_int64_s(void) { @@ -1469,7 +1469,7 @@ struct int_float_int_s { int a; float b; int c; }; void f_int_float_int_s_arg(struct int_float_int_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_int_float_int_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_INT_FLOAT_INT_S:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_INT_FLOAT_INT_S:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct int_float_int_s f_ret_int_float_int_s(void) { @@ -1485,7 +1485,7 @@ struct int64_float_s { int64_t a; float b; }; void f_int64_float_s_arg(struct int64_float_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_int64_float_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_INT64_FLOAT_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_INT64_FLOAT_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct int64_float_s f_ret_int64_float_s(void) { @@ -1627,7 +1627,7 @@ struct double_float16_s { double f; _Float16 g; }; void f_double_float16_s_arg(struct double_float16_s a) {} // ILP32-ILP32F-LABEL: define dso_local void @f_ret_double_float16_s -// ILP32-ILP32F-SAME: (ptr noalias sret([[STRUCT_DOUBLE_FLOAT16_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_DOUBLE_FLOAT16_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F: entry: // // ILP32D-LABEL: define dso_local { double, half } @f_ret_double_float16_s @@ -1729,7 +1729,7 @@ struct float16_int32_s f_ret_float16_int32_s(void) { void f_float16_int64_s_arg(struct float16_int64_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_float16_int64_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_FLOAT16_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_FLOAT16_INT64_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct float16_int64_s f_ret_float16_int64_s(void) { @@ -2005,7 +2005,7 @@ struct int_float16_int_s { int a; _Float16 b; int c; }; void f_int_float16_int_s_arg(struct int_float16_int_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_int_float16_int_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_INT_FLOAT16_INT_S:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_INT_FLOAT16_INT_S:%.*]]) align 4 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct int_float16_int_s f_ret_int_float16_int_s(void) { @@ -2021,7 +2021,7 @@ struct int64_float16_s { int64_t a; _Float16 b; }; void f_int64_float16_s_arg(struct int64_float16_s a) {} // ILP32-ILP32F-ILP32D-LABEL: define dso_local void @f_ret_int64_float16_s -// ILP32-ILP32F-ILP32D-SAME: (ptr noalias sret([[STRUCT_INT64_FLOAT16_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// ILP32-ILP32F-ILP32D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_INT64_FLOAT16_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // ILP32-ILP32F-ILP32D: entry: // struct int64_float16_s f_ret_int64_float16_s(void) { diff --git a/clang/test/CodeGen/RISCV/riscv64-abi.c b/clang/test/CodeGen/RISCV/riscv64-abi.c index 8c857f86ddfff..3e7654851da0e 100644 --- a/clang/test/CodeGen/RISCV/riscv64-abi.c +++ b/clang/test/CodeGen/RISCV/riscv64-abi.c @@ -250,7 +250,7 @@ void f_agg_large(struct large x) { // The address where the struct should be written to will be the first // argument // LP64-LP64F-LP64D-LABEL: define dso_local void @f_agg_large_ret -// LP64-LP64F-LP64D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef signext [[I:%.*]], i8 noundef signext [[J:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef signext [[I:%.*]], i8 noundef signext [[J:%.*]]) #[[ATTR0]] { // LP64-LP64F-LP64D: entry: // struct large f_agg_large_ret(int32_t i, int8_t j) { @@ -268,7 +268,7 @@ void f_vec_large_v32i8(v32i8 x) { } // LP64-LP64F-LP64D-LABEL: define dso_local void @f_vec_large_v32i8_ret -// LP64-LP64F-LP64D-SAME: (ptr noalias sret(<32 x i8>) align 32 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret(<32 x i8>) align 32 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // LP64-LP64F-LP64D: entry: // v32i8 f_vec_large_v32i8_ret(void) { @@ -310,7 +310,7 @@ int f_scalar_stack_3(int32_t a, __int128_t b, double c, long double d, v32i8 e, // to pass a pointer. // LP64-LP64F-LP64D-LABEL: define dso_local void @f_scalar_stack_4 -// LP64-LP64F-LP64D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], i32 noundef signext [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { // LP64-LP64F-LP64D: entry: // struct large f_scalar_stack_4(uint32_t a, __int128_t b, long double c, v32i8 d, @@ -319,7 +319,7 @@ struct large f_scalar_stack_4(uint32_t a, __int128_t b, long double c, v32i8 d, } // LP64-LP64F-LP64D-LABEL: define dso_local void @f_scalar_stack_5 -// LP64-LP64F-LP64D-SAME: (ptr noalias sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], double noundef [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_LARGE:%.*]]) align 8 [[AGG_RESULT:%.*]], double noundef [[A:%.*]], i128 noundef [[B:%.*]], fp128 noundef [[C:%.*]], ptr noundef [[TMP0:%.*]], i8 noundef zeroext [[E:%.*]], i8 noundef signext [[F:%.*]], i8 noundef zeroext [[G:%.*]]) #[[ATTR0]] { // LP64-LP64F-LP64D: entry: // struct large f_scalar_stack_5(double a, __int128_t b, long double c, v32i8 d, @@ -1444,7 +1444,7 @@ struct int_double_int_s { int a; double b; int c; }; void f_int_double_int_s_arg(struct int_double_int_s a) {} // LP64-LP64F-LP64D-LABEL: define dso_local void @f_ret_int_double_int_s -// LP64-LP64F-LP64D-SAME: (ptr noalias sret([[STRUCT_INT_DOUBLE_INT_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { +// LP64-LP64F-LP64D-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_INT_DOUBLE_INT_S:%.*]]) align 8 [[AGG_RESULT:%.*]]) #[[ATTR0]] { // LP64-LP64F-LP64D: entry: // struct int_double_int_s f_ret_int_double_int_s(void) { diff --git a/clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-8Al.c b/clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-8Al.c index e38e6572bd58f..4f6dcbc2c01ec 100644 --- a/clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-8Al.c +++ b/clang/test/CodeGen/SystemZ/gnu-atomic-builtins-i128-8Al.c @@ -20,10 +20,7 @@ __int128 Des; // CHECK-LABEL: @f1( // CHECK-NEXT: entry: -// CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i128, align 8 -// CHECK-NEXT: call void @__atomic_load(i64 noundef 16, ptr noundef nonnull @Ptr, ptr noundef nonnull [[ATOMIC_TEMP]], i32 noundef signext 5) -// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr [[ATOMIC_TEMP]], align 8, !tbaa [[TBAA2:![0-9]+]] -// CHECK-NEXT: store i128 [[TMP0]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] +// CHECK-NEXT: tail call void @__atomic_load(i64 noundef 16, ptr noundef nonnull @Ptr, ptr noundef nonnull [[AGG_RESULT:%.*]], i32 noundef signext 5) // CHECK-NEXT: ret void // __int128 f1() { @@ -33,7 +30,7 @@ __int128 f1() { // CHECK-LABEL: @f2( // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @__atomic_load(i64 noundef 16, ptr noundef nonnull @Ptr, ptr noundef nonnull @Ret, i32 noundef signext 5) -// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Ret, align 8, !tbaa [[TBAA2]] +// CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Ret, align 8, !tbaa [[TBAA2:![0-9]+]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] // CHECK-NEXT: ret void // @@ -66,12 +63,9 @@ void f4() { // CHECK-LABEL: @f5( // CHECK-NEXT: entry: // CHECK-NEXT: [[DOTATOMICTMP:%.*]] = alloca i128, align 8 -// CHECK-NEXT: [[ATOMIC_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[DOTATOMICTMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_exchange(i64 noundef 16, ptr noundef nonnull @Ptr, ptr noundef nonnull [[DOTATOMICTMP]], ptr noundef nonnull [[ATOMIC_TEMP]], i32 noundef signext 5) -// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[ATOMIC_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @__atomic_exchange(i64 noundef 16, ptr noundef nonnull @Ptr, ptr noundef nonnull [[DOTATOMICTMP]], ptr noundef nonnull [[AGG_RESULT:%.*]], i32 noundef signext 5) // CHECK-NEXT: ret void // __int128 f5() { @@ -119,7 +113,7 @@ _Bool f8() { // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_add_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) +// CHECK-NEXT: call void @__atomic_fetch_add_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] // CHECK-NEXT: [[TMP2:%.*]] = add i128 [[TMP1]], [[TMP0]] // CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] @@ -135,7 +129,7 @@ __int128 f9() { // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_sub_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) +// CHECK-NEXT: call void @__atomic_fetch_sub_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] // CHECK-NEXT: [[TMP2:%.*]] = sub i128 [[TMP1]], [[TMP0]] // CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] @@ -151,7 +145,7 @@ __int128 f10() { // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_and_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) +// CHECK-NEXT: call void @__atomic_fetch_and_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] // CHECK-NEXT: [[TMP2:%.*]] = and i128 [[TMP1]], [[TMP0]] // CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] @@ -167,7 +161,7 @@ __int128 f11() { // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_xor_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) +// CHECK-NEXT: call void @__atomic_fetch_xor_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] // CHECK-NEXT: [[TMP2:%.*]] = xor i128 [[TMP1]], [[TMP0]] // CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] @@ -183,7 +177,7 @@ __int128 f12() { // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_or_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) +// CHECK-NEXT: call void @__atomic_fetch_or_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] // CHECK-NEXT: [[TMP2:%.*]] = or i128 [[TMP1]], [[TMP0]] // CHECK-NEXT: store i128 [[TMP2]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] @@ -199,7 +193,7 @@ __int128 f13() { // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_nand_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) +// CHECK-NEXT: call void @__atomic_fetch_nand_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] // CHECK-NEXT: [[TMP2:%.*]] = and i128 [[TMP1]], [[TMP0]] // CHECK-NEXT: [[TMP3:%.*]] = xor i128 [[TMP2]], -1 @@ -212,13 +206,10 @@ __int128 f14() { // CHECK-LABEL: @f15( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_add_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) -// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @__atomic_fetch_add_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[AGG_RESULT:%.*]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: ret void // __int128 f15() { @@ -227,13 +218,10 @@ __int128 f15() { // CHECK-LABEL: @f16( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_sub_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) -// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @__atomic_fetch_sub_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[AGG_RESULT:%.*]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: ret void // __int128 f16() { @@ -242,13 +230,10 @@ __int128 f16() { // CHECK-LABEL: @f17( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_and_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) -// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @__atomic_fetch_and_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[AGG_RESULT:%.*]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: ret void // __int128 f17() { @@ -257,13 +242,10 @@ __int128 f17() { // CHECK-LABEL: @f18( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_xor_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) -// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @__atomic_fetch_xor_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[AGG_RESULT:%.*]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: ret void // __int128 f18() { @@ -272,13 +254,10 @@ __int128 f18() { // CHECK-LABEL: @f19( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_or_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) -// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @__atomic_fetch_or_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[AGG_RESULT:%.*]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: ret void // __int128 f19() { @@ -287,13 +266,10 @@ __int128 f19() { // CHECK-LABEL: @f20( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[INDIRECT_ARG_TEMP:%.*]] = alloca i128, align 8 // CHECK-NEXT: [[TMP0:%.*]] = load i128, ptr @Val, align 8, !tbaa [[TBAA2]] // CHECK-NEXT: store i128 [[TMP0]], ptr [[INDIRECT_ARG_TEMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: call void @__atomic_fetch_nand_16(ptr nonnull sret(i128) align 8 [[TMP]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) -// CHECK-NEXT: [[TMP1:%.*]] = load i128, ptr [[TMP]], align 8, !tbaa [[TBAA2]] -// CHECK-NEXT: store i128 [[TMP1]], ptr [[AGG_RESULT:%.*]], align 8, !tbaa [[TBAA2]] +// CHECK-NEXT: call void @__atomic_fetch_nand_16(ptr dead_on_unwind nonnull writable sret(i128) align 8 [[AGG_RESULT:%.*]], ptr noundef nonnull @Ptr, ptr noundef nonnull [[INDIRECT_ARG_TEMP]], i32 noundef signext 5) // CHECK-NEXT: ret void // __int128 f20() { diff --git a/clang/test/CodeGen/SystemZ/systemz-abi-vector.c b/clang/test/CodeGen/SystemZ/systemz-abi-vector.c index f7606641a3747..6a06d15f22aa3 100644 --- a/clang/test/CodeGen/SystemZ/systemz-abi-vector.c +++ b/clang/test/CodeGen/SystemZ/systemz-abi-vector.c @@ -54,91 +54,91 @@ unsigned int align = __alignof__ (v16i8); // CHECK-VECTOR: @align ={{.*}} global i32 8 v1i8 pass_v1i8(v1i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v1i8(ptr noalias sret(<1 x i8>) align 1 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v1i8(ptr dead_on_unwind noalias writable sret(<1 x i8>) align 1 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <1 x i8> @pass_v1i8(<1 x i8> %{{.*}}) v2i8 pass_v2i8(v2i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v2i8(ptr noalias sret(<2 x i8>) align 2 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v2i8(ptr dead_on_unwind noalias writable sret(<2 x i8>) align 2 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <2 x i8> @pass_v2i8(<2 x i8> %{{.*}}) v4i8 pass_v4i8(v4i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v4i8(ptr noalias sret(<4 x i8>) align 4 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v4i8(ptr dead_on_unwind noalias writable sret(<4 x i8>) align 4 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <4 x i8> @pass_v4i8(<4 x i8> %{{.*}}) v8i8 pass_v8i8(v8i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v8i8(ptr noalias sret(<8 x i8>) align 8 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v8i8(ptr dead_on_unwind noalias writable sret(<8 x i8>) align 8 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <8 x i8> @pass_v8i8(<8 x i8> %{{.*}}) v16i8 pass_v16i8(v16i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v16i8(ptr noalias sret(<16 x i8>) align 16 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v16i8(ptr dead_on_unwind noalias writable sret(<16 x i8>) align 16 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <16 x i8> @pass_v16i8(<16 x i8> %{{.*}}) v32i8 pass_v32i8(v32i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v32i8(ptr noalias sret(<32 x i8>) align 32 %{{.*}}, ptr %0) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_v32i8(ptr noalias sret(<32 x i8>) align 8 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v32i8(ptr dead_on_unwind noalias writable sret(<32 x i8>) align 32 %{{.*}}, ptr %0) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_v32i8(ptr dead_on_unwind noalias writable sret(<32 x i8>) align 8 %{{.*}}, ptr %0) v1i16 pass_v1i16(v1i16 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v1i16(ptr noalias sret(<1 x i16>) align 2 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v1i16(ptr dead_on_unwind noalias writable sret(<1 x i16>) align 2 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <1 x i16> @pass_v1i16(<1 x i16> %{{.*}}) v2i16 pass_v2i16(v2i16 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v2i16(ptr noalias sret(<2 x i16>) align 4 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v2i16(ptr dead_on_unwind noalias writable sret(<2 x i16>) align 4 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <2 x i16> @pass_v2i16(<2 x i16> %{{.*}}) v4i16 pass_v4i16(v4i16 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v4i16(ptr noalias sret(<4 x i16>) align 8 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v4i16(ptr dead_on_unwind noalias writable sret(<4 x i16>) align 8 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <4 x i16> @pass_v4i16(<4 x i16> %{{.*}}) v8i16 pass_v8i16(v8i16 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v8i16(ptr noalias sret(<8 x i16>) align 16 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v8i16(ptr dead_on_unwind noalias writable sret(<8 x i16>) align 16 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <8 x i16> @pass_v8i16(<8 x i16> %{{.*}}) v1i32 pass_v1i32(v1i32 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v1i32(ptr noalias sret(<1 x i32>) align 4 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v1i32(ptr dead_on_unwind noalias writable sret(<1 x i32>) align 4 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <1 x i32> @pass_v1i32(<1 x i32> %{{.*}}) v2i32 pass_v2i32(v2i32 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v2i32(ptr noalias sret(<2 x i32>) align 8 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v2i32(ptr dead_on_unwind noalias writable sret(<2 x i32>) align 8 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <2 x i32> @pass_v2i32(<2 x i32> %{{.*}}) v4i32 pass_v4i32(v4i32 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v4i32(ptr noalias sret(<4 x i32>) align 16 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v4i32(ptr dead_on_unwind noalias writable sret(<4 x i32>) align 16 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <4 x i32> @pass_v4i32(<4 x i32> %{{.*}}) v1i64 pass_v1i64(v1i64 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v1i64(ptr noalias sret(<1 x i64>) align 8 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v1i64(ptr dead_on_unwind noalias writable sret(<1 x i64>) align 8 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <1 x i64> @pass_v1i64(<1 x i64> %{{.*}}) v2i64 pass_v2i64(v2i64 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v2i64(ptr noalias sret(<2 x i64>) align 16 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v2i64(ptr dead_on_unwind noalias writable sret(<2 x i64>) align 16 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <2 x i64> @pass_v2i64(<2 x i64> %{{.*}}) v1i128 pass_v1i128(v1i128 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v1i128(ptr noalias sret(<1 x i128>) align 16 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v1i128(ptr dead_on_unwind noalias writable sret(<1 x i128>) align 16 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <1 x i128> @pass_v1i128(<1 x i128> %{{.*}}) v1f32 pass_v1f32(v1f32 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v1f32(ptr noalias sret(<1 x float>) align 4 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v1f32(ptr dead_on_unwind noalias writable sret(<1 x float>) align 4 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <1 x float> @pass_v1f32(<1 x float> %{{.*}}) v2f32 pass_v2f32(v2f32 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v2f32(ptr noalias sret(<2 x float>) align 8 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v2f32(ptr dead_on_unwind noalias writable sret(<2 x float>) align 8 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <2 x float> @pass_v2f32(<2 x float> %{{.*}}) v4f32 pass_v4f32(v4f32 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v4f32(ptr noalias sret(<4 x float>) align 16 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v4f32(ptr dead_on_unwind noalias writable sret(<4 x float>) align 16 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <4 x float> @pass_v4f32(<4 x float> %{{.*}}) v1f64 pass_v1f64(v1f64 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v1f64(ptr noalias sret(<1 x double>) align 8 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v1f64(ptr dead_on_unwind noalias writable sret(<1 x double>) align 8 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <1 x double> @pass_v1f64(<1 x double> %{{.*}}) v2f64 pass_v2f64(v2f64 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v2f64(ptr noalias sret(<2 x double>) align 16 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v2f64(ptr dead_on_unwind noalias writable sret(<2 x double>) align 16 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <2 x double> @pass_v2f64(<2 x double> %{{.*}}) v1f128 pass_v1f128(v1f128 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_v1f128(ptr noalias sret(<1 x fp128>) align 16 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_v1f128(ptr dead_on_unwind noalias writable sret(<1 x fp128>) align 16 %{{.*}}, ptr %0) // CHECK-VECTOR-LABEL: define{{.*}} <1 x fp128> @pass_v1f128(<1 x fp128> %{{.*}}) @@ -146,62 +146,62 @@ v1f128 pass_v1f128(v1f128 arg) { return arg; } struct agg_v1i8 { v1i8 a; }; struct agg_v1i8 pass_agg_v1i8(struct agg_v1i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_v1i8(ptr noalias sret(%struct.agg_v1i8) align 1 %{{.*}}, i8 %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v1i8(ptr noalias sret(%struct.agg_v1i8) align 1 %{{.*}}, <1 x i8> %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_v1i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v1i8) align 1 %{{.*}}, i8 %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v1i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v1i8) align 1 %{{.*}}, <1 x i8> %{{.*}}) struct agg_v2i8 { v2i8 a; }; struct agg_v2i8 pass_agg_v2i8(struct agg_v2i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_v2i8(ptr noalias sret(%struct.agg_v2i8) align 2 %{{.*}}, i16 %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v2i8(ptr noalias sret(%struct.agg_v2i8) align 2 %{{.*}}, <2 x i8> %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_v2i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v2i8) align 2 %{{.*}}, i16 %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v2i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v2i8) align 2 %{{.*}}, <2 x i8> %{{.*}}) struct agg_v4i8 { v4i8 a; }; struct agg_v4i8 pass_agg_v4i8(struct agg_v4i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_v4i8(ptr noalias sret(%struct.agg_v4i8) align 4 %{{.*}}, i32 %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v4i8(ptr noalias sret(%struct.agg_v4i8) align 4 %{{.*}}, <4 x i8> %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_v4i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v4i8) align 4 %{{.*}}, i32 %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v4i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v4i8) align 4 %{{.*}}, <4 x i8> %{{.*}}) struct agg_v8i8 { v8i8 a; }; struct agg_v8i8 pass_agg_v8i8(struct agg_v8i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_v8i8(ptr noalias sret(%struct.agg_v8i8) align 8 %{{.*}}, i64 %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v8i8(ptr noalias sret(%struct.agg_v8i8) align 8 %{{.*}}, <8 x i8> %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_v8i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v8i8) align 8 %{{.*}}, i64 %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v8i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v8i8) align 8 %{{.*}}, <8 x i8> %{{.*}}) struct agg_v16i8 { v16i8 a; }; struct agg_v16i8 pass_agg_v16i8(struct agg_v16i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_v16i8(ptr noalias sret(%struct.agg_v16i8) align 16 %{{.*}}, ptr %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v16i8(ptr noalias sret(%struct.agg_v16i8) align 8 %{{.*}}, <16 x i8> %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_v16i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v16i8) align 16 %{{.*}}, ptr %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v16i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v16i8) align 8 %{{.*}}, <16 x i8> %{{.*}}) struct agg_v32i8 { v32i8 a; }; struct agg_v32i8 pass_agg_v32i8(struct agg_v32i8 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_v32i8(ptr noalias sret(%struct.agg_v32i8) align 32 %{{.*}}, ptr %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v32i8(ptr noalias sret(%struct.agg_v32i8) align 8 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_v32i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v32i8) align 32 %{{.*}}, ptr %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_v32i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v32i8) align 8 %{{.*}}, ptr %{{.*}}) // Verify that the following are *not* vector-like aggregate types struct agg_novector1 { v4i8 a; v4i8 b; }; struct agg_novector1 pass_agg_novector1(struct agg_novector1 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_novector1(ptr noalias sret(%struct.agg_novector1) align 4 %{{.*}}, i64 %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector1(ptr noalias sret(%struct.agg_novector1) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_novector1(ptr dead_on_unwind noalias writable sret(%struct.agg_novector1) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector1(ptr dead_on_unwind noalias writable sret(%struct.agg_novector1) align 4 %{{.*}}, i64 %{{.*}}) struct agg_novector2 { v4i8 a; float b; }; struct agg_novector2 pass_agg_novector2(struct agg_novector2 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_novector2(ptr noalias sret(%struct.agg_novector2) align 4 %{{.*}}, i64 %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector2(ptr noalias sret(%struct.agg_novector2) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_novector2(ptr dead_on_unwind noalias writable sret(%struct.agg_novector2) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector2(ptr dead_on_unwind noalias writable sret(%struct.agg_novector2) align 4 %{{.*}}, i64 %{{.*}}) struct agg_novector3 { v4i8 a; int : 0; }; struct agg_novector3 pass_agg_novector3(struct agg_novector3 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_novector3(ptr noalias sret(%struct.agg_novector3) align 4 %{{.*}}, i32 %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector3(ptr noalias sret(%struct.agg_novector3) align 4 %{{.*}}, i32 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_novector3(ptr dead_on_unwind noalias writable sret(%struct.agg_novector3) align 4 %{{.*}}, i32 %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector3(ptr dead_on_unwind noalias writable sret(%struct.agg_novector3) align 4 %{{.*}}, i32 %{{.*}}) struct agg_novector4 { v4i8 a __attribute__((aligned (8))); }; struct agg_novector4 pass_agg_novector4(struct agg_novector4 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_novector4(ptr noalias sret(%struct.agg_novector4) align 8 %{{.*}}, i64 %{{.*}}) -// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector4(ptr noalias sret(%struct.agg_novector4) align 8 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_novector4(ptr dead_on_unwind noalias writable sret(%struct.agg_novector4) align 8 %{{.*}}, i64 %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @pass_agg_novector4(ptr dead_on_unwind noalias writable sret(%struct.agg_novector4) align 8 %{{.*}}, i64 %{{.*}}) // Accessing variable argument lists v1i8 va_v1i8(__builtin_va_list l) { return __builtin_va_arg(l, v1i8); } -// CHECK-LABEL: define{{.*}} void @va_v1i8(ptr noalias sret(<1 x i8>) align 1 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_v1i8(ptr dead_on_unwind noalias writable sret(<1 x i8>) align 1 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -230,7 +230,7 @@ v1i8 va_v1i8(__builtin_va_list l) { return __builtin_va_arg(l, v1i8); } // CHECK-VECTOR: ret <1 x i8> [[RET]] v2i8 va_v2i8(__builtin_va_list l) { return __builtin_va_arg(l, v2i8); } -// CHECK-LABEL: define{{.*}} void @va_v2i8(ptr noalias sret(<2 x i8>) align 2 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_v2i8(ptr dead_on_unwind noalias writable sret(<2 x i8>) align 2 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -259,7 +259,7 @@ v2i8 va_v2i8(__builtin_va_list l) { return __builtin_va_arg(l, v2i8); } // CHECK-VECTOR: ret <2 x i8> [[RET]] v4i8 va_v4i8(__builtin_va_list l) { return __builtin_va_arg(l, v4i8); } -// CHECK-LABEL: define{{.*}} void @va_v4i8(ptr noalias sret(<4 x i8>) align 4 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_v4i8(ptr dead_on_unwind noalias writable sret(<4 x i8>) align 4 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -288,7 +288,7 @@ v4i8 va_v4i8(__builtin_va_list l) { return __builtin_va_arg(l, v4i8); } // CHECK-VECTOR: ret <4 x i8> [[RET]] v8i8 va_v8i8(__builtin_va_list l) { return __builtin_va_arg(l, v8i8); } -// CHECK-LABEL: define{{.*}} void @va_v8i8(ptr noalias sret(<8 x i8>) align 8 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_v8i8(ptr dead_on_unwind noalias writable sret(<8 x i8>) align 8 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -317,7 +317,7 @@ v8i8 va_v8i8(__builtin_va_list l) { return __builtin_va_arg(l, v8i8); } // CHECK-VECTOR: ret <8 x i8> [[RET]] v16i8 va_v16i8(__builtin_va_list l) { return __builtin_va_arg(l, v16i8); } -// CHECK-LABEL: define{{.*}} void @va_v16i8(ptr noalias sret(<16 x i8>) align 16 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_v16i8(ptr dead_on_unwind noalias writable sret(<16 x i8>) align 16 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -346,7 +346,7 @@ v16i8 va_v16i8(__builtin_va_list l) { return __builtin_va_arg(l, v16i8); } // CHECK-VECTOR: ret <16 x i8> [[RET]] v32i8 va_v32i8(__builtin_va_list l) { return __builtin_va_arg(l, v32i8); } -// CHECK-LABEL: define{{.*}} void @va_v32i8(ptr noalias sret(<32 x i8>) align 32 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_v32i8(ptr dead_on_unwind noalias writable sret(<32 x i8>) align 32 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -366,7 +366,7 @@ v32i8 va_v32i8(__builtin_va_list l) { return __builtin_va_arg(l, v32i8); } // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi ptr [ [[RAW_REG_ADDR]], %{{.*}} ], [ [[RAW_MEM_ADDR]], %{{.*}} ] // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load ptr, ptr [[VA_ARG_ADDR]] // CHECK: ret void -// CHECK-VECTOR-LABEL: define{{.*}} void @va_v32i8(ptr noalias sret(<32 x i8>) align 8 %{{.*}}, ptr %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @va_v32i8(ptr dead_on_unwind noalias writable sret(<32 x i8>) align 8 %{{.*}}, ptr %{{.*}}) // CHECK-VECTOR: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK-VECTOR: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK-VECTOR: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -388,7 +388,7 @@ v32i8 va_v32i8(__builtin_va_list l) { return __builtin_va_arg(l, v32i8); } // CHECK-VECTOR: ret void struct agg_v1i8 va_agg_v1i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v1i8); } -// CHECK-LABEL: define{{.*}} void @va_agg_v1i8(ptr noalias sret(%struct.agg_v1i8) align 1 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_agg_v1i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v1i8) align 1 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -407,7 +407,7 @@ struct agg_v1i8 va_agg_v1i8(__builtin_va_list l) { return __builtin_va_arg(l, st // CHECK: store ptr [[OVERFLOW_ARG_AREA2]], ptr [[OVERFLOW_ARG_AREA_PTR]] // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi ptr [ [[RAW_REG_ADDR]], %{{.*}} ], [ [[RAW_MEM_ADDR]], %{{.*}} ] // CHECK: ret void -// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v1i8(ptr noalias sret(%struct.agg_v1i8) align 1 %{{.*}}, ptr %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v1i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v1i8) align 1 %{{.*}}, ptr %{{.*}}) // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 2 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load ptr, ptr [[OVERFLOW_ARG_AREA_PTR]] // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, ptr [[OVERFLOW_ARG_AREA]], i64 8 @@ -415,7 +415,7 @@ struct agg_v1i8 va_agg_v1i8(__builtin_va_list l) { return __builtin_va_arg(l, st // CHECK-VECTOR: ret void struct agg_v2i8 va_agg_v2i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v2i8); } -// CHECK-LABEL: define{{.*}} void @va_agg_v2i8(ptr noalias sret(%struct.agg_v2i8) align 2 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_agg_v2i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v2i8) align 2 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -434,7 +434,7 @@ struct agg_v2i8 va_agg_v2i8(__builtin_va_list l) { return __builtin_va_arg(l, st // CHECK: store ptr [[OVERFLOW_ARG_AREA2]], ptr [[OVERFLOW_ARG_AREA_PTR]] // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi ptr [ [[RAW_REG_ADDR]], %{{.*}} ], [ [[RAW_MEM_ADDR]], %{{.*}} ] // CHECK: ret void -// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v2i8(ptr noalias sret(%struct.agg_v2i8) align 2 %{{.*}}, ptr %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v2i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v2i8) align 2 %{{.*}}, ptr %{{.*}}) // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 2 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load ptr, ptr [[OVERFLOW_ARG_AREA_PTR]] // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, ptr [[OVERFLOW_ARG_AREA]], i64 8 @@ -442,7 +442,7 @@ struct agg_v2i8 va_agg_v2i8(__builtin_va_list l) { return __builtin_va_arg(l, st // CHECK-VECTOR: ret void struct agg_v4i8 va_agg_v4i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v4i8); } -// CHECK-LABEL: define{{.*}} void @va_agg_v4i8(ptr noalias sret(%struct.agg_v4i8) align 4 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_agg_v4i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v4i8) align 4 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -461,7 +461,7 @@ struct agg_v4i8 va_agg_v4i8(__builtin_va_list l) { return __builtin_va_arg(l, st // CHECK: store ptr [[OVERFLOW_ARG_AREA2]], ptr [[OVERFLOW_ARG_AREA_PTR]] // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi ptr [ [[RAW_REG_ADDR]], %{{.*}} ], [ [[RAW_MEM_ADDR]], %{{.*}} ] // CHECK: ret void -// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v4i8(ptr noalias sret(%struct.agg_v4i8) align 4 %{{.*}}, ptr %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v4i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v4i8) align 4 %{{.*}}, ptr %{{.*}}) // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 2 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load ptr, ptr [[OVERFLOW_ARG_AREA_PTR]] // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, ptr [[OVERFLOW_ARG_AREA]], i64 8 @@ -469,7 +469,7 @@ struct agg_v4i8 va_agg_v4i8(__builtin_va_list l) { return __builtin_va_arg(l, st // CHECK-VECTOR: ret void struct agg_v8i8 va_agg_v8i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v8i8); } -// CHECK-LABEL: define{{.*}} void @va_agg_v8i8(ptr noalias sret(%struct.agg_v8i8) align 8 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_agg_v8i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v8i8) align 8 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -488,7 +488,7 @@ struct agg_v8i8 va_agg_v8i8(__builtin_va_list l) { return __builtin_va_arg(l, st // CHECK: store ptr [[OVERFLOW_ARG_AREA2]], ptr [[OVERFLOW_ARG_AREA_PTR]] // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi ptr [ [[RAW_REG_ADDR]], %{{.*}} ], [ [[RAW_MEM_ADDR]], %{{.*}} ] // CHECK: ret void -// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v8i8(ptr noalias sret(%struct.agg_v8i8) align 8 %{{.*}}, ptr %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v8i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v8i8) align 8 %{{.*}}, ptr %{{.*}}) // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 2 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load ptr, ptr [[OVERFLOW_ARG_AREA_PTR]] // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, ptr [[OVERFLOW_ARG_AREA]], i64 8 @@ -496,7 +496,7 @@ struct agg_v8i8 va_agg_v8i8(__builtin_va_list l) { return __builtin_va_arg(l, st // CHECK-VECTOR: ret void struct agg_v16i8 va_agg_v16i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v16i8); } -// CHECK-LABEL: define{{.*}} void @va_agg_v16i8(ptr noalias sret(%struct.agg_v16i8) align 16 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_agg_v16i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v16i8) align 16 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -516,7 +516,7 @@ struct agg_v16i8 va_agg_v16i8(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi ptr [ [[RAW_REG_ADDR]], %{{.*}} ], [ [[RAW_MEM_ADDR]], %{{.*}} ] // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load ptr, ptr [[VA_ARG_ADDR]] // CHECK: ret void -// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v16i8(ptr noalias sret(%struct.agg_v16i8) align 8 %{{.*}}, ptr %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v16i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v16i8) align 8 %{{.*}}, ptr %{{.*}}) // CHECK-VECTOR: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 2 // CHECK-VECTOR: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load ptr, ptr [[OVERFLOW_ARG_AREA_PTR]] // CHECK-VECTOR: [[OVERFLOW_ARG_AREA1:%[^ ]+]] = getelementptr i8, ptr [[OVERFLOW_ARG_AREA]], i64 16 @@ -524,7 +524,7 @@ struct agg_v16i8 va_agg_v16i8(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK-VECTOR: ret void struct agg_v32i8 va_agg_v32i8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_v32i8); } -// CHECK-LABEL: define{{.*}} void @va_agg_v32i8(ptr noalias sret(%struct.agg_v32i8) align 32 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_agg_v32i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v32i8) align 32 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -544,7 +544,7 @@ struct agg_v32i8 va_agg_v32i8(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi ptr [ [[RAW_REG_ADDR]], %{{.*}} ], [ [[RAW_MEM_ADDR]], %{{.*}} ] // CHECK: [[INDIRECT_ARG:%[^ ]+]] = load ptr, ptr [[VA_ARG_ADDR]] // CHECK: ret void -// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v32i8(ptr noalias sret(%struct.agg_v32i8) align 8 %{{.*}}, ptr %{{.*}}) +// CHECK-VECTOR-LABEL: define{{.*}} void @va_agg_v32i8(ptr dead_on_unwind noalias writable sret(%struct.agg_v32i8) align 8 %{{.*}}, ptr %{{.*}}) // CHECK-VECTOR: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK-VECTOR: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK-VECTOR: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 diff --git a/clang/test/CodeGen/SystemZ/systemz-abi.c b/clang/test/CodeGen/SystemZ/systemz-abi.c index 7b2c04ece185f..65a2bc9bbb680 100644 --- a/clang/test/CodeGen/SystemZ/systemz-abi.c +++ b/clang/test/CodeGen/SystemZ/systemz-abi.c @@ -43,7 +43,7 @@ long long pass_longlong(long long arg) { return arg; } // CHECK-LABEL: define{{.*}} i64 @pass_longlong(i64 %{{.*}}) __int128 pass_int128(__int128 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_int128(ptr noalias sret(i128) align 8 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_int128(ptr dead_on_unwind noalias writable sret(i128) align 8 %{{.*}}, ptr %0) float pass_float(float arg) { return arg; } // CHECK-LABEL: define{{.*}} float @pass_float(float %{{.*}}) @@ -52,125 +52,125 @@ double pass_double(double arg) { return arg; } // CHECK-LABEL: define{{.*}} double @pass_double(double %{{.*}}) long double pass_longdouble(long double arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_longdouble(ptr noalias sret(fp128) align 8 %{{.*}}, ptr %0) +// CHECK-LABEL: define{{.*}} void @pass_longdouble(ptr dead_on_unwind noalias writable sret(fp128) align 8 %{{.*}}, ptr %0) // Complex types _Complex char pass_complex_char(_Complex char arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_complex_char(ptr noalias sret({ i8, i8 }) align 1 %{{.*}}, ptr %{{.*}}arg) +// CHECK-LABEL: define{{.*}} void @pass_complex_char(ptr dead_on_unwind noalias writable sret({ i8, i8 }) align 1 %{{.*}}, ptr %{{.*}}arg) _Complex short pass_complex_short(_Complex short arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_complex_short(ptr noalias sret({ i16, i16 }) align 2 %{{.*}}, ptr %{{.*}}arg) +// CHECK-LABEL: define{{.*}} void @pass_complex_short(ptr dead_on_unwind noalias writable sret({ i16, i16 }) align 2 %{{.*}}, ptr %{{.*}}arg) _Complex int pass_complex_int(_Complex int arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_complex_int(ptr noalias sret({ i32, i32 }) align 4 %{{.*}}, ptr %{{.*}}arg) +// CHECK-LABEL: define{{.*}} void @pass_complex_int(ptr dead_on_unwind noalias writable sret({ i32, i32 }) align 4 %{{.*}}, ptr %{{.*}}arg) _Complex long pass_complex_long(_Complex long arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_complex_long(ptr noalias sret({ i64, i64 }) align 8 %{{.*}}, ptr %{{.*}}arg) +// CHECK-LABEL: define{{.*}} void @pass_complex_long(ptr dead_on_unwind noalias writable sret({ i64, i64 }) align 8 %{{.*}}, ptr %{{.*}}arg) _Complex long long pass_complex_longlong(_Complex long long arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_complex_longlong(ptr noalias sret({ i64, i64 }) align 8 %{{.*}}, ptr %{{.*}}arg) +// CHECK-LABEL: define{{.*}} void @pass_complex_longlong(ptr dead_on_unwind noalias writable sret({ i64, i64 }) align 8 %{{.*}}, ptr %{{.*}}arg) _Complex float pass_complex_float(_Complex float arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_complex_float(ptr noalias sret({ float, float }) align 4 %{{.*}}, ptr %{{.*}}arg) +// CHECK-LABEL: define{{.*}} void @pass_complex_float(ptr dead_on_unwind noalias writable sret({ float, float }) align 4 %{{.*}}, ptr %{{.*}}arg) _Complex double pass_complex_double(_Complex double arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_complex_double(ptr noalias sret({ double, double }) align 8 %{{.*}}, ptr %{{.*}}arg) +// CHECK-LABEL: define{{.*}} void @pass_complex_double(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %{{.*}}, ptr %{{.*}}arg) _Complex long double pass_complex_longdouble(_Complex long double arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_complex_longdouble(ptr noalias sret({ fp128, fp128 }) align 8 %{{.*}}, ptr %{{.*}}arg) +// CHECK-LABEL: define{{.*}} void @pass_complex_longdouble(ptr dead_on_unwind noalias writable sret({ fp128, fp128 }) align 8 %{{.*}}, ptr %{{.*}}arg) // Aggregate types struct agg_1byte { char a[1]; }; struct agg_1byte pass_agg_1byte(struct agg_1byte arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_1byte(ptr noalias sret(%struct.agg_1byte) align 1 %{{.*}}, i8 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_1byte(ptr dead_on_unwind noalias writable sret(%struct.agg_1byte) align 1 %{{.*}}, i8 %{{.*}}) struct agg_2byte { char a[2]; }; struct agg_2byte pass_agg_2byte(struct agg_2byte arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_2byte(ptr noalias sret(%struct.agg_2byte) align 1 %{{.*}}, i16 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_2byte(ptr dead_on_unwind noalias writable sret(%struct.agg_2byte) align 1 %{{.*}}, i16 %{{.*}}) struct agg_3byte { char a[3]; }; struct agg_3byte pass_agg_3byte(struct agg_3byte arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_3byte(ptr noalias sret(%struct.agg_3byte) align 1 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_3byte(ptr dead_on_unwind noalias writable sret(%struct.agg_3byte) align 1 %{{.*}}, ptr %{{.*}}) struct agg_4byte { char a[4]; }; struct agg_4byte pass_agg_4byte(struct agg_4byte arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_4byte(ptr noalias sret(%struct.agg_4byte) align 1 %{{.*}}, i32 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_4byte(ptr dead_on_unwind noalias writable sret(%struct.agg_4byte) align 1 %{{.*}}, i32 %{{.*}}) struct agg_5byte { char a[5]; }; struct agg_5byte pass_agg_5byte(struct agg_5byte arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_5byte(ptr noalias sret(%struct.agg_5byte) align 1 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_5byte(ptr dead_on_unwind noalias writable sret(%struct.agg_5byte) align 1 %{{.*}}, ptr %{{.*}}) struct agg_6byte { char a[6]; }; struct agg_6byte pass_agg_6byte(struct agg_6byte arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_6byte(ptr noalias sret(%struct.agg_6byte) align 1 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_6byte(ptr dead_on_unwind noalias writable sret(%struct.agg_6byte) align 1 %{{.*}}, ptr %{{.*}}) struct agg_7byte { char a[7]; }; struct agg_7byte pass_agg_7byte(struct agg_7byte arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_7byte(ptr noalias sret(%struct.agg_7byte) align 1 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_7byte(ptr dead_on_unwind noalias writable sret(%struct.agg_7byte) align 1 %{{.*}}, ptr %{{.*}}) struct agg_8byte { char a[8]; }; struct agg_8byte pass_agg_8byte(struct agg_8byte arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_8byte(ptr noalias sret(%struct.agg_8byte) align 1 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_8byte(ptr dead_on_unwind noalias writable sret(%struct.agg_8byte) align 1 %{{.*}}, i64 %{{.*}}) struct agg_16byte { char a[16]; }; struct agg_16byte pass_agg_16byte(struct agg_16byte arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_16byte(ptr noalias sret(%struct.agg_16byte) align 1 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_16byte(ptr dead_on_unwind noalias writable sret(%struct.agg_16byte) align 1 %{{.*}}, ptr %{{.*}}) // Float-like aggregate types struct agg_float { float a; }; struct agg_float pass_agg_float(struct agg_float arg) { return arg; } -// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg_float(ptr noalias sret(%struct.agg_float) align 4 %{{.*}}, float %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg_float(ptr noalias sret(%struct.agg_float) align 4 %{{.*}}, i32 %{{.*}}) +// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg_float(ptr dead_on_unwind noalias writable sret(%struct.agg_float) align 4 %{{.*}}, float %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg_float(ptr dead_on_unwind noalias writable sret(%struct.agg_float) align 4 %{{.*}}, i32 %{{.*}}) struct agg_double { double a; }; struct agg_double pass_agg_double(struct agg_double arg) { return arg; } -// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg_double(ptr noalias sret(%struct.agg_double) align 8 %{{.*}}, double %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg_double(ptr noalias sret(%struct.agg_double) align 8 %{{.*}}, i64 %{{.*}}) +// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg_double(ptr dead_on_unwind noalias writable sret(%struct.agg_double) align 8 %{{.*}}, double %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg_double(ptr dead_on_unwind noalias writable sret(%struct.agg_double) align 8 %{{.*}}, i64 %{{.*}}) struct agg_longdouble { long double a; }; struct agg_longdouble pass_agg_longdouble(struct agg_longdouble arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_longdouble(ptr noalias sret(%struct.agg_longdouble) align 8 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_longdouble(ptr dead_on_unwind noalias writable sret(%struct.agg_longdouble) align 8 %{{.*}}, ptr %{{.*}}) struct agg_float_a8 { float a __attribute__((aligned (8))); }; struct agg_float_a8 pass_agg_float_a8(struct agg_float_a8 arg) { return arg; } -// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg_float_a8(ptr noalias sret(%struct.agg_float_a8) align 8 %{{.*}}, double %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg_float_a8(ptr noalias sret(%struct.agg_float_a8) align 8 %{{.*}}, i64 %{{.*}}) +// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg_float_a8(ptr dead_on_unwind noalias writable sret(%struct.agg_float_a8) align 8 %{{.*}}, double %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg_float_a8(ptr dead_on_unwind noalias writable sret(%struct.agg_float_a8) align 8 %{{.*}}, i64 %{{.*}}) struct agg_float_a16 { float a __attribute__((aligned (16))); }; struct agg_float_a16 pass_agg_float_a16(struct agg_float_a16 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_float_a16(ptr noalias sret(%struct.agg_float_a16) align 16 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_float_a16(ptr dead_on_unwind noalias writable sret(%struct.agg_float_a16) align 16 %{{.*}}, ptr %{{.*}}) // Verify that the following are *not* float-like aggregate types struct agg_nofloat1 { float a; float b; }; struct agg_nofloat1 pass_agg_nofloat1(struct agg_nofloat1 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_nofloat1(ptr noalias sret(%struct.agg_nofloat1) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_nofloat1(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat1) align 4 %{{.*}}, i64 %{{.*}}) struct agg_nofloat2 { float a; int b; }; struct agg_nofloat2 pass_agg_nofloat2(struct agg_nofloat2 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_nofloat2(ptr noalias sret(%struct.agg_nofloat2) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_nofloat2(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat2) align 4 %{{.*}}, i64 %{{.*}}) struct agg_nofloat3 { float a; int : 0; }; struct agg_nofloat3 pass_agg_nofloat3(struct agg_nofloat3 arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_agg_nofloat3(ptr noalias sret(%struct.agg_nofloat3) align 4 %{{.*}}, i32 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_agg_nofloat3(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat3) align 4 %{{.*}}, i32 %{{.*}}) // Union types likewise are *not* float-like aggregate types union union_float { float a; }; union union_float pass_union_float(union union_float arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_union_float(ptr noalias sret(%union.union_float) align 4 %{{.*}}, i32 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_union_float(ptr dead_on_unwind noalias writable sret(%union.union_float) align 4 %{{.*}}, i32 %{{.*}}) union union_double { double a; }; union union_double pass_union_double(union union_double arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @pass_union_double(ptr noalias sret(%union.union_double) align 8 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @pass_union_double(ptr dead_on_unwind noalias writable sret(%union.union_double) align 8 %{{.*}}, i64 %{{.*}}) // Accessing variable argument lists @@ -267,7 +267,7 @@ double va_double(__builtin_va_list l) { return __builtin_va_arg(l, double); } // CHECK: ret double [[RET]] long double va_longdouble(__builtin_va_list l) { return __builtin_va_arg(l, long double); } -// CHECK-LABEL: define{{.*}} void @va_longdouble(ptr noalias sret(fp128) align 8 %{{.*}}, ptr %{{.*}}) +// CHECK-LABEL: define{{.*}} void @va_longdouble(ptr dead_on_unwind noalias writable sret(fp128) align 8 %{{.*}}, ptr %{{.*}}) // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -291,7 +291,7 @@ long double va_longdouble(__builtin_va_list l) { return __builtin_va_arg(l, long // CHECK: ret void _Complex char va_complex_char(__builtin_va_list l) { return __builtin_va_arg(l, _Complex char); } -// CHECK-LABEL: define{{.*}} void @va_complex_char(ptr noalias sret({ i8, i8 }) align 1 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_complex_char(ptr dead_on_unwind noalias writable sret({ i8, i8 }) align 1 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -313,7 +313,7 @@ _Complex char va_complex_char(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK: ret void struct agg_1byte va_agg_1byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_1byte); } -// CHECK-LABEL: define{{.*}} void @va_agg_1byte(ptr noalias sret(%struct.agg_1byte) align 1 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_1byte(ptr dead_on_unwind noalias writable sret(%struct.agg_1byte) align 1 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -334,7 +334,7 @@ struct agg_1byte va_agg_1byte(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK: ret void struct agg_2byte va_agg_2byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_2byte); } -// CHECK-LABEL: define{{.*}} void @va_agg_2byte(ptr noalias sret(%struct.agg_2byte) align 1 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_2byte(ptr dead_on_unwind noalias writable sret(%struct.agg_2byte) align 1 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -355,7 +355,7 @@ struct agg_2byte va_agg_2byte(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK: ret void struct agg_3byte va_agg_3byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_3byte); } -// CHECK-LABEL: define{{.*}} void @va_agg_3byte(ptr noalias sret(%struct.agg_3byte) align 1 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_3byte(ptr dead_on_unwind noalias writable sret(%struct.agg_3byte) align 1 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -377,7 +377,7 @@ struct agg_3byte va_agg_3byte(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK: ret void struct agg_4byte va_agg_4byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_4byte); } -// CHECK-LABEL: define{{.*}} void @va_agg_4byte(ptr noalias sret(%struct.agg_4byte) align 1 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_4byte(ptr dead_on_unwind noalias writable sret(%struct.agg_4byte) align 1 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -398,7 +398,7 @@ struct agg_4byte va_agg_4byte(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK: ret void struct agg_8byte va_agg_8byte(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_8byte); } -// CHECK-LABEL: define{{.*}} void @va_agg_8byte(ptr noalias sret(%struct.agg_8byte) align 1 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_8byte(ptr dead_on_unwind noalias writable sret(%struct.agg_8byte) align 1 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -419,7 +419,7 @@ struct agg_8byte va_agg_8byte(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK: ret void struct agg_float va_agg_float(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_float); } -// CHECK-LABEL: define{{.*}} void @va_agg_float(ptr noalias sret(%struct.agg_float) align 4 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_float(ptr dead_on_unwind noalias writable sret(%struct.agg_float) align 4 %{{.*}}, ptr %{{.*}} // HARD-FLOAT: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 1 // SOFT-FLOAT: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] @@ -443,7 +443,7 @@ struct agg_float va_agg_float(__builtin_va_list l) { return __builtin_va_arg(l, // CHECK: ret void struct agg_double va_agg_double(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_double); } -// CHECK-LABEL: define{{.*}} void @va_agg_double(ptr noalias sret(%struct.agg_double) align 8 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_double(ptr dead_on_unwind noalias writable sret(%struct.agg_double) align 8 %{{.*}}, ptr %{{.*}} // HARD-FLOAT: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 1 // SOFT-FLOAT: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] @@ -467,7 +467,7 @@ struct agg_double va_agg_double(__builtin_va_list l) { return __builtin_va_arg(l // CHECK: ret void struct agg_longdouble va_agg_longdouble(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_longdouble); } -// CHECK-LABEL: define{{.*}} void @va_agg_longdouble(ptr noalias sret(%struct.agg_longdouble) align 8 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_longdouble(ptr dead_on_unwind noalias writable sret(%struct.agg_longdouble) align 8 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -489,7 +489,7 @@ struct agg_longdouble va_agg_longdouble(__builtin_va_list l) { return __builtin_ // CHECK: ret void struct agg_float_a8 va_agg_float_a8(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_float_a8); } -// CHECK-LABEL: define{{.*}} void @va_agg_float_a8(ptr noalias sret(%struct.agg_float_a8) align 8 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_float_a8(ptr dead_on_unwind noalias writable sret(%struct.agg_float_a8) align 8 %{{.*}}, ptr %{{.*}} // HARD-FLOAT: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 1 // SOFT-FLOAT: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] @@ -513,7 +513,7 @@ struct agg_float_a8 va_agg_float_a8(__builtin_va_list l) { return __builtin_va_a // CHECK: ret void struct agg_float_a16 va_agg_float_a16(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_float_a16); } -// CHECK-LABEL: define{{.*}} void @va_agg_float_a16(ptr noalias sret(%struct.agg_float_a16) align 16 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_float_a16(ptr dead_on_unwind noalias writable sret(%struct.agg_float_a16) align 16 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -535,7 +535,7 @@ struct agg_float_a16 va_agg_float_a16(__builtin_va_list l) { return __builtin_va // CHECK: ret void struct agg_nofloat1 va_agg_nofloat1(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_nofloat1); } -// CHECK-LABEL: define{{.*}} void @va_agg_nofloat1(ptr noalias sret(%struct.agg_nofloat1) align 4 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_nofloat1(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat1) align 4 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -556,7 +556,7 @@ struct agg_nofloat1 va_agg_nofloat1(__builtin_va_list l) { return __builtin_va_a // CHECK: ret void struct agg_nofloat2 va_agg_nofloat2(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_nofloat2); } -// CHECK-LABEL: define{{.*}} void @va_agg_nofloat2(ptr noalias sret(%struct.agg_nofloat2) align 4 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_nofloat2(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat2) align 4 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 @@ -577,7 +577,7 @@ struct agg_nofloat2 va_agg_nofloat2(__builtin_va_list l) { return __builtin_va_a // CHECK: ret void struct agg_nofloat3 va_agg_nofloat3(__builtin_va_list l) { return __builtin_va_arg(l, struct agg_nofloat3); } -// CHECK-LABEL: define{{.*}} void @va_agg_nofloat3(ptr noalias sret(%struct.agg_nofloat3) align 4 %{{.*}}, ptr %{{.*}} +// CHECK-LABEL: define{{.*}} void @va_agg_nofloat3(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat3) align 4 %{{.*}}, ptr %{{.*}} // CHECK: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0 // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]] // CHECK: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5 diff --git a/clang/test/CodeGen/SystemZ/systemz-abi.cpp b/clang/test/CodeGen/SystemZ/systemz-abi.cpp index 08bf08c3803f4..06be85421ba17 100644 --- a/clang/test/CodeGen/SystemZ/systemz-abi.cpp +++ b/clang/test/CodeGen/SystemZ/systemz-abi.cpp @@ -6,20 +6,20 @@ class agg_float_class { float a; }; class agg_float_class pass_agg_float_class(class agg_float_class arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z20pass_agg_float_class15agg_float_class(ptr noalias sret(%class.agg_float_class) align 4 %{{.*}}, float %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @_Z20pass_agg_float_class15agg_float_class(ptr noalias sret(%class.agg_float_class) align 4 %{{.*}}, i32 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z20pass_agg_float_class15agg_float_class(ptr dead_on_unwind noalias writable sret(%class.agg_float_class) align 4 %{{.*}}, float %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @_Z20pass_agg_float_class15agg_float_class(ptr dead_on_unwind noalias writable sret(%class.agg_float_class) align 4 %{{.*}}, i32 %{{.*}}) class agg_double_class { double a; }; class agg_double_class pass_agg_double_class(class agg_double_class arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z21pass_agg_double_class16agg_double_class(ptr noalias sret(%class.agg_double_class) align 8 %{{.*}}, double %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @_Z21pass_agg_double_class16agg_double_class(ptr noalias sret(%class.agg_double_class) align 8 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z21pass_agg_double_class16agg_double_class(ptr dead_on_unwind noalias writable sret(%class.agg_double_class) align 8 %{{.*}}, double %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @_Z21pass_agg_double_class16agg_double_class(ptr dead_on_unwind noalias writable sret(%class.agg_double_class) align 8 %{{.*}}, i64 %{{.*}}) // This structure is passed in a GPR in C++ (and C, checked in systemz-abi.c). struct agg_float_cpp { float a; int : 0; }; struct agg_float_cpp pass_agg_float_cpp(struct agg_float_cpp arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(ptr noalias sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(ptr noalias sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(ptr dead_on_unwind noalias writable sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @_Z18pass_agg_float_cpp13agg_float_cpp(ptr dead_on_unwind noalias writable sret(%struct.agg_float_cpp) align 4 %{{.*}}, i32 %{{.*}}) // A field member of empty class type in C++ makes the record nonhomogeneous, @@ -27,31 +27,31 @@ struct agg_float_cpp pass_agg_float_cpp(struct agg_float_cpp arg) { return arg; struct empty { }; struct agg_nofloat_empty { float a; empty dummy; }; struct agg_nofloat_empty pass_agg_nofloat_empty(struct agg_nofloat_empty arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z22pass_agg_nofloat_empty17agg_nofloat_empty(ptr noalias sret(%struct.agg_nofloat_empty) align 4 %{{.*}}, i64 %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @_Z22pass_agg_nofloat_empty17agg_nofloat_empty(ptr noalias sret(%struct.agg_nofloat_empty) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z22pass_agg_nofloat_empty17agg_nofloat_empty(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_empty) align 4 %{{.*}}, i64 %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @_Z22pass_agg_nofloat_empty17agg_nofloat_empty(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_empty) align 4 %{{.*}}, i64 %{{.*}}) struct agg_float_empty { float a; [[no_unique_address]] empty dummy; }; struct agg_float_empty pass_agg_float_empty(struct agg_float_empty arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z20pass_agg_float_empty15agg_float_empty(ptr noalias sret(%struct.agg_float_empty) align 4 %{{.*}}, float %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @_Z20pass_agg_float_empty15agg_float_empty(ptr noalias sret(%struct.agg_float_empty) align 4 %{{.*}}, i32 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z20pass_agg_float_empty15agg_float_empty(ptr dead_on_unwind noalias writable sret(%struct.agg_float_empty) align 4 %{{.*}}, float %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @_Z20pass_agg_float_empty15agg_float_empty(ptr dead_on_unwind noalias writable sret(%struct.agg_float_empty) align 4 %{{.*}}, i32 %{{.*}}) struct agg_nofloat_emptyarray { float a; [[no_unique_address]] empty dummy[3]; }; struct agg_nofloat_emptyarray pass_agg_nofloat_emptyarray(struct agg_nofloat_emptyarray arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z27pass_agg_nofloat_emptyarray22agg_nofloat_emptyarray(ptr noalias sret(%struct.agg_nofloat_emptyarray) align 4 %{{.*}}, i64 %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @_Z27pass_agg_nofloat_emptyarray22agg_nofloat_emptyarray(ptr noalias sret(%struct.agg_nofloat_emptyarray) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z27pass_agg_nofloat_emptyarray22agg_nofloat_emptyarray(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_emptyarray) align 4 %{{.*}}, i64 %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @_Z27pass_agg_nofloat_emptyarray22agg_nofloat_emptyarray(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_emptyarray) align 4 %{{.*}}, i64 %{{.*}}) // And likewise for members of base classes. struct noemptybase { empty dummy; }; struct agg_nofloat_emptybase : noemptybase { float a; }; struct agg_nofloat_emptybase pass_agg_nofloat_emptybase(struct agg_nofloat_emptybase arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(ptr noalias sret(%struct.agg_nofloat_emptybase) align 4 %{{.*}}, i64 %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(ptr noalias sret(%struct.agg_nofloat_emptybase) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_emptybase) align 4 %{{.*}}, i64 %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @_Z26pass_agg_nofloat_emptybase21agg_nofloat_emptybase(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_emptybase) align 4 %{{.*}}, i64 %{{.*}}) struct emptybase { [[no_unique_address]] empty dummy; }; struct agg_float_emptybase : emptybase { float a; }; struct agg_float_emptybase pass_agg_float_emptybase(struct agg_float_emptybase arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z24pass_agg_float_emptybase19agg_float_emptybase(ptr noalias sret(%struct.agg_float_emptybase) align 4 %{{.*}}, float %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @_Z24pass_agg_float_emptybase19agg_float_emptybase(ptr noalias sret(%struct.agg_float_emptybase) align 4 %{{.*}}, i32 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z24pass_agg_float_emptybase19agg_float_emptybase(ptr dead_on_unwind noalias writable sret(%struct.agg_float_emptybase) align 4 %{{.*}}, float %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @_Z24pass_agg_float_emptybase19agg_float_emptybase(ptr dead_on_unwind noalias writable sret(%struct.agg_float_emptybase) align 4 %{{.*}}, i32 %{{.*}}) struct noemptybasearray { [[no_unique_address]] empty dummy[3]; }; struct agg_nofloat_emptybasearray : noemptybasearray { float a; }; struct agg_nofloat_emptybasearray pass_agg_nofloat_emptybasearray(struct agg_nofloat_emptybasearray arg) { return arg; } -// CHECK-LABEL: define{{.*}} void @_Z31pass_agg_nofloat_emptybasearray26agg_nofloat_emptybasearray(ptr noalias sret(%struct.agg_nofloat_emptybasearray) align 4 %{{.*}}, i64 %{{.*}}) -// SOFT-FLOAT-LABEL: define{{.*}} void @_Z31pass_agg_nofloat_emptybasearray26agg_nofloat_emptybasearray(ptr noalias sret(%struct.agg_nofloat_emptybasearray) align 4 %{{.*}}, i64 %{{.*}}) +// CHECK-LABEL: define{{.*}} void @_Z31pass_agg_nofloat_emptybasearray26agg_nofloat_emptybasearray(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_emptybasearray) align 4 %{{.*}}, i64 %{{.*}}) +// SOFT-FLOAT-LABEL: define{{.*}} void @_Z31pass_agg_nofloat_emptybasearray26agg_nofloat_emptybasearray(ptr dead_on_unwind noalias writable sret(%struct.agg_nofloat_emptybasearray) align 4 %{{.*}}, i64 %{{.*}}) diff --git a/clang/test/CodeGen/SystemZ/systemz-inline-asm.c b/clang/test/CodeGen/SystemZ/systemz-inline-asm.c index 0d614f8cbb905..e38d37cd345e2 100644 --- a/clang/test/CodeGen/SystemZ/systemz-inline-asm.c +++ b/clang/test/CodeGen/SystemZ/systemz-inline-asm.c @@ -123,7 +123,7 @@ double test_f64(double f, double g) { long double test_f128(long double f, long double g) { asm("axbr %0, %2" : "=f" (f) : "0" (f), "f" (g)); return f; -// CHECK: define{{.*}} void @test_f128(ptr noalias nocapture writeonly sret(fp128) align 8 [[DEST:%.*]], ptr nocapture noundef readonly %0, ptr nocapture noundef readonly %1) +// CHECK: define{{.*}} void @test_f128(ptr dead_on_unwind noalias nocapture writable writeonly sret(fp128) align 8 [[DEST:%.*]], ptr nocapture noundef readonly %0, ptr nocapture noundef readonly %1) // CHECK: %f = load fp128, ptr %0 // CHECK: %g = load fp128, ptr %1 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g) diff --git a/clang/test/CodeGen/WebAssembly/wasm-arguments.c b/clang/test/CodeGen/WebAssembly/wasm-arguments.c index 1b54b6401db0e..a0914fc768809 100644 --- a/clang/test/CodeGen/WebAssembly/wasm-arguments.c +++ b/clang/test/CodeGen/WebAssembly/wasm-arguments.c @@ -25,9 +25,9 @@ typedef struct { void struct_arg(s1 i) {} // Structs should be returned sret and not simplified by the frontend. -// WEBASSEMBLY32: define void @struct_ret(ptr noalias sret(%struct.s1) align 4 %agg.result) +// WEBASSEMBLY32: define void @struct_ret(ptr dead_on_unwind noalias writable sret(%struct.s1) align 4 %agg.result) // WEBASSEMBLY32: ret void -// WEBASSEMBLY64: define void @struct_ret(ptr noalias sret(%struct.s1) align 4 %agg.result) +// WEBASSEMBLY64: define void @struct_ret(ptr dead_on_unwind noalias writable sret(%struct.s1) align 4 %agg.result) // WEBASSEMBLY64: ret void // Except with the experimental multivalue ABI, which returns structs by value @@ -103,9 +103,9 @@ union simple_union { void union_arg(union simple_union s) {} // Unions should be returned sret and not simplified by the frontend. -// WEBASSEMBLY32: define void @union_ret(ptr noalias sret(%union.simple_union) align 4 %agg.result) +// WEBASSEMBLY32: define void @union_ret(ptr dead_on_unwind noalias writable sret(%union.simple_union) align 4 %agg.result) // WEBASSEMBLY32: ret void -// WEBASSEMBLY64: define void @union_ret(ptr noalias sret(%union.simple_union) align 4 %agg.result) +// WEBASSEMBLY64: define void @union_ret(ptr dead_on_unwind noalias writable sret(%union.simple_union) align 4 %agg.result) // WEBASSEMBLY64: ret void // The experimental multivalue ABI returns them by value, though. @@ -129,8 +129,8 @@ typedef struct { void bitfield_arg(bitfield1 bf1) {} // And returned via sret pointers. -// WEBASSEMBLY32: define void @bitfield_ret(ptr noalias sret(%struct.bitfield1) align 4 %agg.result) -// WEBASSEMBLY64: define void @bitfield_ret(ptr noalias sret(%struct.bitfield1) align 4 %agg.result) +// WEBASSEMBLY32: define void @bitfield_ret(ptr dead_on_unwind noalias writable sret(%struct.bitfield1) align 4 %agg.result) +// WEBASSEMBLY64: define void @bitfield_ret(ptr dead_on_unwind noalias writable sret(%struct.bitfield1) align 4 %agg.result) // Except, of course, in the experimental multivalue ABI // EXPERIMENTAL-MV: define %struct.bitfield1 @bitfield_ret() diff --git a/clang/test/CodeGen/WebAssembly/wasm-varargs.c b/clang/test/CodeGen/WebAssembly/wasm-varargs.c index da22ad6a1b2e9..c475de19ae448 100644 --- a/clang/test/CodeGen/WebAssembly/wasm-varargs.c +++ b/clang/test/CodeGen/WebAssembly/wasm-varargs.c @@ -68,7 +68,7 @@ struct S { }; // CHECK-LABEL: define {{[^@]+}}@test_struct -// CHECK-SAME: (ptr noalias sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef [[FMT:%.*]], ...) #[[ATTR0]] { +// CHECK-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef [[FMT:%.*]], ...) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FMT_ADDR:%.*]] = alloca ptr, align 4 // CHECK-NEXT: [[VA:%.*]] = alloca ptr, align 4 @@ -96,7 +96,7 @@ struct S test_struct(char *fmt, ...) { struct Z {}; // CHECK-LABEL: define {{[^@]+}}@test_empty_struct -// CHECK-SAME: (ptr noalias sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef [[FMT:%.*]], ...) #[[ATTR0]] { +// CHECK-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr noundef [[FMT:%.*]], ...) #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[FMT_ADDR:%.*]] = alloca ptr, align 4 // CHECK-NEXT: [[VA:%.*]] = alloca ptr, align 4 diff --git a/clang/test/CodeGen/X86/x86_32-arguments-darwin.c b/clang/test/CodeGen/X86/x86_32-arguments-darwin.c index 69d1156acf7eb..8eeba631157d0 100644 --- a/clang/test/CodeGen/X86/x86_32-arguments-darwin.c +++ b/clang/test/CodeGen/X86/x86_32-arguments-darwin.c @@ -71,7 +71,7 @@ struct s10 { // Small vectors and 1 x {i64,double} are returned in registers // CHECK: i32 @f11() -// CHECK: void @f12(ptr noalias sret(<2 x i32>) align 8 %agg.result) +// CHECK: void @f12(ptr dead_on_unwind noalias writable sret(<2 x i32>) align 8 %agg.result) // CHECK: i64 @f13() // CHECK: i64 @f14() // CHECK: <2 x i64> @f15() @@ -93,11 +93,11 @@ T16 f16(void) { while (1) {} } // 128-bits). // CHECK: i32 @f17() -// CHECK: void @f18(ptr noalias sret(%struct.anon.{{[0-9]+}}) align 8 %agg.result) -// CHECK: void @f19(ptr noalias sret(%struct.anon.{{[0-9]+}}) align 8 %agg.result) -// CHECK: void @f20(ptr noalias sret(%struct.anon.{{[0-9]+}}) align 8 %agg.result) -// CHECK: void @f21(ptr noalias sret(%struct.anon.{{[0-9]+}}) align 16 %agg.result) -// CHECK: void @f22(ptr noalias sret(%struct.anon.{{[0-9]+}}) align 16 %agg.result) +// CHECK: void @f18(ptr dead_on_unwind noalias writable sret(%struct.anon.{{[0-9]+}}) align 8 %agg.result) +// CHECK: void @f19(ptr dead_on_unwind noalias writable sret(%struct.anon.{{[0-9]+}}) align 8 %agg.result) +// CHECK: void @f20(ptr dead_on_unwind noalias writable sret(%struct.anon.{{[0-9]+}}) align 8 %agg.result) +// CHECK: void @f21(ptr dead_on_unwind noalias writable sret(%struct.anon.{{[0-9]+}}) align 16 %agg.result) +// CHECK: void @f22(ptr dead_on_unwind noalias writable sret(%struct.anon.{{[0-9]+}}) align 16 %agg.result) struct { T11 a; } f17(void) { while (1) {} } struct { T12 a; } f18(void) { while (1) {} } struct { T13 a; } f19(void) { while (1) {} } @@ -116,11 +116,11 @@ struct { struct {} a; struct { float a[1]; } b; } f25(void) { while (1) {} } // Small structures are handled recursively // CHECK: i32 @f26() -// CHECK: void @f27(ptr noalias sret(%struct.s27) align 1 %agg.result) +// CHECK: void @f27(ptr dead_on_unwind noalias writable sret(%struct.s27) align 1 %agg.result) struct s26 { struct { char a, b; } a; struct { char a, b; } b; } f26(void) { while (1) {} } struct s27 { struct { char a, b, c; } a; struct { char a; } b; } f27(void) { while (1) {} } -// CHECK: void @f28(ptr noalias sret(%struct.s28) align 4 %agg.result) +// CHECK: void @f28(ptr dead_on_unwind noalias writable sret(%struct.s28) align 4 %agg.result) struct s28 { int a; int b[]; } f28(void) { while (1) {} } // CHECK-LABEL: define{{.*}} i16 @f29() @@ -150,7 +150,7 @@ struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) { while ( // CHECK-LABEL: define{{.*}} float @f37() struct s37 { float c[1][1]; } f37(void) { while (1) {} } -// CHECK-LABEL: define{{.*}} void @f38(ptr noalias sret(%struct.s38) align 2 %agg.result) +// CHECK-LABEL: define{{.*}} void @f38(ptr dead_on_unwind noalias writable sret(%struct.s38) align 2 %agg.result) struct s38 { char a[3]; short b; } f38(void) { while (1) {} } // CHECK-LABEL: define{{.*}} void @f39(ptr noundef byval(%struct.s39) align 16 %x) diff --git a/clang/test/CodeGen/X86/x86_32-arguments-iamcu.c b/clang/test/CodeGen/X86/x86_32-arguments-iamcu.c index c2b8f23ba5f33..2700bda1e7edf 100644 --- a/clang/test/CodeGen/X86/x86_32-arguments-iamcu.c +++ b/clang/test/CodeGen/X86/x86_32-arguments-iamcu.c @@ -58,7 +58,7 @@ st4_t retSmallStruct(st4_t r) { return r; } // CHECK-LABEL: define{{.*}} i64 @retPaddedStruct(i32 %r.coerce0, i32 %r.coerce1) st5_t retPaddedStruct(st5_t r) { return r; } -// CHECK-LABEL: define{{.*}} void @retLargeStruct(ptr noalias sret(%struct.st12_t) align 4 %agg.result, i32 noundef %i1, ptr noundef byval(%struct.st12_t) align 4 %r) +// CHECK-LABEL: define{{.*}} void @retLargeStruct(ptr dead_on_unwind noalias writable sret(%struct.st12_t) align 4 %agg.result, i32 noundef %i1, ptr noundef byval(%struct.st12_t) align 4 %r) st12_t retLargeStruct(int i1, st12_t r) { return r; } // CHECK-LABEL: define{{.*}} i32 @varArgs(i32 noundef %i1, ...) diff --git a/clang/test/CodeGen/X86/x86_64-arguments-nacl.c b/clang/test/CodeGen/X86/x86_64-arguments-nacl.c index 3f91ed1b1c461..4d820aef8fd2d 100644 --- a/clang/test/CodeGen/X86/x86_64-arguments-nacl.c +++ b/clang/test/CodeGen/X86/x86_64-arguments-nacl.c @@ -61,7 +61,7 @@ void f12_1(struct s12 a0) {} // Check that sret parameter is accounted for when checking available integer // registers. -// CHECK: define{{.*}} void @f13(ptr noalias sret(%struct.s13_0) align 8 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, ptr noundef byval({{.*}}) align 8 %e, i32 noundef %f) +// CHECK: define{{.*}} void @f13(ptr dead_on_unwind noalias writable sret(%struct.s13_0) align 8 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, ptr noundef byval({{.*}}) align 8 %e, i32 noundef %f) struct s13_0 { long long f0[3]; }; struct s13_1 { long long f0[2]; }; diff --git a/clang/test/CodeGen/X86/x86_64-arguments-win32.c b/clang/test/CodeGen/X86/x86_64-arguments-win32.c index 31aa0546a3c86..8768e73a854aa 100644 --- a/clang/test/CodeGen/X86/x86_64-arguments-win32.c +++ b/clang/test/CodeGen/X86/x86_64-arguments-win32.c @@ -27,5 +27,5 @@ void f6(_Complex double a) {} // CHECK-LABEL: define dso_local i64 @f7() _Complex float f7(void) { return 1.0; } -// CHECK-LABEL: define dso_local void @f8(ptr noalias sret({ double, double }) align 8 %agg.result) +// CHECK-LABEL: define dso_local void @f8(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result) _Complex double f8(void) { return 1.0; } diff --git a/clang/test/CodeGen/X86/x86_64-arguments.c b/clang/test/CodeGen/X86/x86_64-arguments.c index b2c4283b5e6fe..cf5636cfd518b 100644 --- a/clang/test/CodeGen/X86/x86_64-arguments.c +++ b/clang/test/CodeGen/X86/x86_64-arguments.c @@ -47,7 +47,7 @@ void f7(e7 a0) { // Test merging/passing of upper eightbyte with X87 class. // -// CHECK-LABEL: define{{.*}} void @f8_1(ptr noalias sret(%union.u8) align 16 %agg.result) +// CHECK-LABEL: define{{.*}} void @f8_1(ptr dead_on_unwind noalias writable sret(%union.u8) align 16 %agg.result) // CHECK-LABEL: define{{.*}} void @f8_2(ptr noundef byval(%union.u8) align 16 %a0) union u8 { long double a; @@ -63,7 +63,7 @@ struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} } struct s10 { int a; int b; int : 0; }; void f10(struct s10 a0) {} -// CHECK-LABEL: define{{.*}} void @f11(ptr noalias sret(%union.anon) align 16 %agg.result) +// CHECK-LABEL: define{{.*}} void @f11(ptr dead_on_unwind noalias writable sret(%union.anon) align 16 %agg.result) union { long double a; float b; } f11(void) { while (1) {} } // CHECK-LABEL: define{{.*}} i32 @f12_0() @@ -74,7 +74,7 @@ void f12_1(struct s12 a0) {} // Check that sret parameter is accounted for when checking available integer // registers. -// CHECK: define{{.*}} void @f13(ptr noalias sret(%struct.s13_0) align 8 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, ptr noundef byval({{.*}}) align 8 %e, i32 noundef %f) +// CHECK: define{{.*}} void @f13(ptr dead_on_unwind noalias writable sret(%struct.s13_0) align 8 %agg.result, i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, ptr noundef byval({{.*}}) align 8 %e, i32 noundef %f) struct s13_0 { long long f0[3]; }; struct s13_1 { long long f0[2]; }; diff --git a/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c index 9c96dfb9e33ee..1e6a4500cc886 100644 --- a/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c +++ b/clang/test/CodeGen/aarch64-sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c @@ -59,7 +59,7 @@ typedef int8_t vec_int8 __attribute__((vector_size(N / 8))); // CHECK128-NEXT: ret <16 x i8> [[CASTFIXEDSVE]] // CHECK-LABEL: define{{.*}} void @f2( -// CHECK-SAME: ptr noalias nocapture writeonly sret(<[[#div(VBITS,8)]] x i8>) align 16 %agg.result, ptr nocapture noundef readonly %0) +// CHECK-SAME: ptr dead_on_unwind noalias nocapture writable writeonly sret(<[[#div(VBITS,8)]] x i8>) align 16 %agg.result, ptr nocapture noundef readonly %0) // CHECK-NEXT: entry: // CHECK-NEXT: [[X:%.*]] = load <[[#div(VBITS,8)]] x i8>, ptr [[TMP0:%.*]], align 16, [[TBAA6:!tbaa !.*]] // CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) diff --git a/clang/test/CodeGen/aarch64-varargs.c b/clang/test/CodeGen/aarch64-varargs.c index f2ce7d59a8cce..44b87029e7b3d 100644 --- a/clang/test/CodeGen/aarch64-varargs.c +++ b/clang/test/CodeGen/aarch64-varargs.c @@ -601,7 +601,7 @@ typedef struct __attribute__((aligned(32))) { __int128 val; } overaligned_int128_struct; overaligned_int128_struct overaligned_int128_struct_test(void) { -// CHECK-LABEL: define{{.*}} void @overaligned_int128_struct_test(ptr noalias sret(%struct.overaligned_int128_struct) align 32 %agg.result) +// CHECK-LABEL: define{{.*}} void @overaligned_int128_struct_test(ptr dead_on_unwind noalias writable sret(%struct.overaligned_int128_struct) align 32 %agg.result) return va_arg(the_list, overaligned_int128_struct); // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, ptr getelementptr inbounds (%struct.__va_list, ptr @the_list, i32 0, i32 3) // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 @@ -804,7 +804,7 @@ typedef struct { __int128 val __attribute__((aligned(32))); } overaligned_int128_struct_member; overaligned_int128_struct_member overaligned_int128_struct_member_test(void) { -// CHECK-LABEL: define{{.*}} void @overaligned_int128_struct_member_test(ptr noalias sret(%struct.overaligned_int128_struct_member) align 32 %agg.result) +// CHECK-LABEL: define{{.*}} void @overaligned_int128_struct_member_test(ptr dead_on_unwind noalias writable sret(%struct.overaligned_int128_struct_member) align 32 %agg.result) return va_arg(the_list, overaligned_int128_struct_member); // CHECK: [[GR_OFFS:%[a-z_0-9]+]] = load i32, ptr getelementptr inbounds (%struct.__va_list, ptr @the_list, i32 0, i32 3) // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[GR_OFFS]], 0 diff --git a/clang/test/CodeGen/aggregate-assign-call.c b/clang/test/CodeGen/aggregate-assign-call.c index b5c7f213dcbe2..d6571269456a4 100644 --- a/clang/test/CodeGen/aggregate-assign-call.c +++ b/clang/test/CodeGen/aggregate-assign-call.c @@ -63,11 +63,11 @@ struct S baz(int i, volatile int *j) { // // O1: call void @llvm.lifetime.end.p0({{[^,]*}}, ptr %[[TMP1_ALLOCA]]) // - // O1: call void @foo_int(ptr sret(%struct.S) align 4 %[[TMP1_ALLOCA]], + // O1: call void @foo_int(ptr dead_on_unwind writable sret(%struct.S) align 4 %[[TMP1_ALLOCA]], // O1: call void @llvm.memcpy // O1: call void @llvm.lifetime.end.p0({{[^,]*}}, ptr %[[TMP1_ALLOCA]]) // O1: call void @llvm.lifetime.start.p0({{[^,]*}}, ptr %[[TMP2_ALLOCA]]) - // O1: call void @foo_int(ptr sret(%struct.S) align 4 %[[TMP2_ALLOCA]], + // O1: call void @foo_int(ptr dead_on_unwind writable sret(%struct.S) align 4 %[[TMP2_ALLOCA]], // O1: call void @llvm.memcpy // O1: call void @llvm.lifetime.end.p0({{[^,]*}}, ptr %[[TMP2_ALLOCA]]) r = foo_int(({ diff --git a/clang/test/CodeGen/aligned-sret.c b/clang/test/CodeGen/aligned-sret.c index 4759d69219a6a..4e1f86e7f07a6 100644 --- a/clang/test/CodeGen/aligned-sret.c +++ b/clang/test/CodeGen/aligned-sret.c @@ -4,7 +4,7 @@ typedef __attribute__((__ext_vector_type__(4),__aligned__(16))) double simd_doub typedef struct { simd_double4 columns[4]; } simd_double4x4; typedef simd_double4x4 matrix_double4x4; -// CHECK: define{{.*}} void @ident(ptr noalias sret(%struct.simd_double4x4) align 16 %agg.result +// CHECK: define{{.*}} void @ident(ptr dead_on_unwind noalias writable sret(%struct.simd_double4x4) align 16 %agg.result matrix_double4x4 ident(matrix_double4x4 x) { return x; } diff --git a/clang/test/CodeGen/arc/arguments.c b/clang/test/CodeGen/arc/arguments.c index a913984e13f85..648a2ea3ce9c1 100644 --- a/clang/test/CodeGen/arc/arguments.c +++ b/clang/test/CodeGen/arc/arguments.c @@ -22,7 +22,7 @@ void cf1(cs1 i) {} typedef struct { int cc; } s2; -// CHECK: define{{.*}} void @f2(ptr noalias sret(%struct.s2) align 4 %agg.result) +// CHECK: define{{.*}} void @f2(ptr dead_on_unwind noalias writable sret(%struct.s2) align 4 %agg.result) s2 f2(void) { s2 foo; return foo; @@ -32,7 +32,7 @@ typedef struct { int cc; int dd; } s3; -// CHECK: define{{.*}} void @f3(ptr noalias sret(%struct.s3) align 4 %agg.result) +// CHECK: define{{.*}} void @f3(ptr dead_on_unwind noalias writable sret(%struct.s3) align 4 %agg.result) s3 f3(void) { s3 foo; return foo; @@ -128,8 +128,8 @@ void st3(s16 a, s16 b, s16 c) {} // 1 sret + 1 i32 + 2*(i32 coerce) + 4*(i32 coerce) + 1 byval s16 st4(int x, s8 a, s16 b, s16 c) { return b; } -// CHECK: define{{.*}} void @st4(ptr noalias sret(%struct.s16) align 4 %agg.result, i32 inreg noundef %x, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) +// CHECK: define{{.*}} void @st4(ptr dead_on_unwind noalias writable sret(%struct.s16) align 4 %agg.result, i32 inreg noundef %x, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) // 1 sret + 2*(i32 coerce) + 4*(i32 coerce) + 4*(i32 coerce) s16 st5(s8 a, s16 b, s16 c) { return b; } -// CHECK: define{{.*}} void @st5(ptr noalias sret(%struct.s16) align 4 %agg.result, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) +// CHECK: define{{.*}} void @st5(ptr dead_on_unwind noalias writable sret(%struct.s16) align 4 %agg.result, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) diff --git a/clang/test/CodeGen/arm-aapcs-vfp.c b/clang/test/CodeGen/arm-aapcs-vfp.c index 5caf93016cd2e..9fae33f476d35 100644 --- a/clang/test/CodeGen/arm-aapcs-vfp.c +++ b/clang/test/CodeGen/arm-aapcs-vfp.c @@ -126,7 +126,7 @@ void test_vfp_stack_gpr_split_1(double a, double b, double c, double d, double e // CHECK: define{{.*}} arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_2(double noundef %a, double noundef %b, double noundef %c, double noundef %d, double noundef %e, double noundef %f, double noundef %g, double noundef %h, double noundef %i, i32 noundef %j, [2 x i64] %k.coerce) void test_vfp_stack_gpr_split_2(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, struct_long_long_int k) {} -// CHECK: define{{.*}} arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_3(ptr noalias sret(%struct.struct_long_long_int) align 8 %agg.result, double noundef %a, double noundef %b, double noundef %c, double noundef %d, double noundef %e, double noundef %f, double noundef %g, double noundef %h, double noundef %i, [2 x i64] %k.coerce) +// CHECK: define{{.*}} arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_3(ptr dead_on_unwind noalias writable sret(%struct.struct_long_long_int) align 8 %agg.result, double noundef %a, double noundef %b, double noundef %c, double noundef %d, double noundef %e, double noundef %f, double noundef %g, double noundef %h, double noundef %i, [2 x i64] %k.coerce) struct_long_long_int test_vfp_stack_gpr_split_3(double a, double b, double c, double d, double e, double f, double g, double h, double i, struct_long_long_int k) {} typedef struct { int a; int b:4; int c; } struct_int_bitfield_int; diff --git a/clang/test/CodeGen/arm-arguments.c b/clang/test/CodeGen/arm-arguments.c index 17e4d3abd9767..8fe2016315f27 100644 --- a/clang/test/CodeGen/arm-arguments.c +++ b/clang/test/CodeGen/arm-arguments.c @@ -29,13 +29,13 @@ struct s4 { struct s4_0 { int f0; } f0; }; struct s4 f4(void) {} // APCS-GNU-LABEL: define{{.*}} void @f5( -// APCS-GNU: ptr noalias sret +// APCS-GNU: ptr dead_on_unwind noalias writable sret // AAPCS-LABEL: define{{.*}} arm_aapcscc i32 @f5() struct s5 { struct { } f0; int f1; }; struct s5 f5(void) {} // APCS-GNU-LABEL: define{{.*}} void @f6( -// APCS-GNU: ptr noalias sret +// APCS-GNU: ptr dead_on_unwind noalias writable sret // AAPCS-LABEL: define{{.*}} arm_aapcscc i32 @f6() struct s6 { int f0[1]; }; struct s6 f6(void) {} @@ -46,7 +46,7 @@ struct s7 { struct { int : 0; } f0; }; struct s7 f7(void) {} // APCS-GNU-LABEL: define{{.*}} void @f8( -// APCS-GNU: ptr noalias sret +// APCS-GNU: ptr dead_on_unwind noalias writable sret // AAPCS-LABEL: define{{.*}} arm_aapcscc void @f8() struct s8 { struct { int : 0; } f0[1]; }; struct s8 f8(void) {} @@ -62,7 +62,7 @@ struct s10 { int f0; int : 0; int : 0; }; struct s10 f10(void) {} // APCS-GNU-LABEL: define{{.*}} void @f11( -// APCS-GNU: ptr noalias sret +// APCS-GNU: ptr dead_on_unwind noalias writable sret // AAPCS-LABEL: define{{.*}} arm_aapcscc i32 @f11() struct s11 { int : 0; int f0; }; struct s11 f11(void) {} @@ -73,7 +73,7 @@ union u12 { char f0; short f1; int f2; }; union u12 f12(void) {} // APCS-GNU-LABEL: define{{.*}} void @f13( -// APCS-GNU: ptr noalias sret +// APCS-GNU: ptr dead_on_unwind noalias writable sret // FIXME: This should return a float. // AAPCS-FIXME: darm_aapcscc efine float @f13() @@ -81,7 +81,7 @@ struct s13 { float f0; }; struct s13 f13(void) {} // APCS-GNU-LABEL: define{{.*}} void @f14( -// APCS-GNU: ptr noalias sret +// APCS-GNU: ptr dead_on_unwind noalias writable sret // AAPCS-LABEL: define{{.*}} arm_aapcscc i32 @f14() union u14 { float f0; }; union u14 f14(void) {} @@ -105,13 +105,13 @@ struct s18 { short f0; char f1 : 4; }; struct s18 f18(void) {} // APCS-GNU-LABEL: define{{.*}} void @f19( -// APCS-GNU: ptr noalias sret +// APCS-GNU: ptr dead_on_unwind noalias writable sret // AAPCS-LABEL: define{{.*}} arm_aapcscc i32 @f19() struct s19 { int f0; struct s8 f1; }; struct s19 f19(void) {} // APCS-GNU-LABEL: define{{.*}} void @f20( -// APCS-GNU: ptr noalias sret +// APCS-GNU: ptr dead_on_unwind noalias writable sret // AAPCS-LABEL: define{{.*}} arm_aapcscc i32 @f20() struct s20 { struct s8 f1; int f0; }; struct s20 f20(void) {} @@ -129,10 +129,10 @@ struct s21 f21(void) {} // APCS-GNU-LABEL: define{{.*}} i128 @f27() // AAPCS-LABEL: define{{.*}} arm_aapcscc i16 @f22() // AAPCS-LABEL: define{{.*}} arm_aapcscc i32 @f23() -// AAPCS: define{{.*}} arm_aapcscc void @f24({{.*}} noalias sret -// AAPCS: define{{.*}} arm_aapcscc void @f25({{.*}} noalias sret -// AAPCS: define{{.*}} arm_aapcscc void @f26({{.*}} noalias sret -// AAPCS: define{{.*}} arm_aapcscc void @f27({{.*}} noalias sret +// AAPCS: define{{.*}} arm_aapcscc void @f24({{.*}} dead_on_unwind noalias writable sret +// AAPCS: define{{.*}} arm_aapcscc void @f25({{.*}} dead_on_unwind noalias writable sret +// AAPCS: define{{.*}} arm_aapcscc void @f26({{.*}} dead_on_unwind noalias writable sret +// AAPCS: define{{.*}} arm_aapcscc void @f27({{.*}} dead_on_unwind noalias writable sret _Complex char f22(void) {} _Complex short f23(void) {} _Complex int f24(void) {} @@ -150,8 +150,8 @@ struct s28 f28() {} struct s29 { _Complex short f0; }; struct s29 f29() {} -// APCS-GNU: define{{.*}} void @f30({{.*}} noalias sret -// AAPCS: define{{.*}} arm_aapcscc void @f30({{.*}} noalias sret +// APCS-GNU: define{{.*}} void @f30({{.*}} dead_on_unwind noalias writable sret +// AAPCS: define{{.*}} arm_aapcscc void @f30({{.*}} dead_on_unwind noalias writable sret struct s30 { _Complex int f0; }; struct s30 f30() {} diff --git a/clang/test/CodeGen/arm-homogenous.c b/clang/test/CodeGen/arm-homogenous.c index dbfb5fb284467..44a539598eb9b 100644 --- a/clang/test/CodeGen/arm-homogenous.c +++ b/clang/test/CodeGen/arm-homogenous.c @@ -27,7 +27,7 @@ void test_union_with_first_floats(void) { void test_return_union_with_first_floats(void) { g_u_f = returns_union_with_first_floats(); } -// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(ptr sret(%union.union_with_first_floats) align 4) +// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_first_floats(ptr dead_on_unwind writable sret(%union.union_with_first_floats) align 4) /* This is not a homogenous aggregate - fundamental types are different */ typedef union { @@ -47,7 +47,7 @@ void test_union_with_non_first_floats(void) { void test_return_union_with_non_first_floats(void) { g_u_nf_f = returns_union_with_non_first_floats(); } -// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(ptr sret(%union.union_with_non_first_floats) align 4) +// CHECK: declare arm_aapcs_vfpcc void @returns_union_with_non_first_floats(ptr dead_on_unwind writable sret(%union.union_with_non_first_floats) align 4) /* This is not a homogenous aggregate - fundamental types are different */ typedef struct { @@ -67,7 +67,7 @@ void test_struct_with_union_with_first_floats(void) { void test_return_struct_with_union_with_first_floats(void) { g_s_f = returns_struct_with_union_with_first_floats(); } -// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(ptr sret(%struct.struct_with_union_with_first_floats) align 4) +// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_first_floats(ptr dead_on_unwind writable sret(%struct.struct_with_union_with_first_floats) align 4) /* This is not a homogenous aggregate - fundamental types are different */ typedef struct { @@ -87,7 +87,7 @@ void test_struct_with_union_with_non_first_floats(void) { void test_return_struct_with_union_with_non_first_floats(void) { g_s_nf_f = returns_struct_with_union_with_non_first_floats(); } -// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(ptr sret(%struct.struct_with_union_with_non_first_floats) align 4) +// CHECK: declare arm_aapcs_vfpcc void @returns_struct_with_union_with_non_first_floats(ptr dead_on_unwind writable sret(%struct.struct_with_union_with_non_first_floats) align 4) /* Plain array is not a homogenous aggregate */ extern void takes_array_of_floats(float a[4]); diff --git a/clang/test/CodeGen/arm-neon-vld.c b/clang/test/CodeGen/arm-neon-vld.c index 697992edb5f6f..959c07cc2219b 100644 --- a/clang/test/CodeGen/arm-neon-vld.c +++ b/clang/test/CodeGen/arm-neon-vld.c @@ -11,7 +11,7 @@ // CHECK-LABEL: @test_vld1_f16_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float16x4x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.float16x4x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float16x4x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float16x4x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x [[HALF:half|i16]]>, <4 x [[HALF]]> } @llvm.{{aarch64.neon.ld1x2.v4f16.p0|arm.neon.vld1x2.v4i16.p0}}(ptr %a) // CHECK: store { <4 x [[HALF]]>, <4 x [[HALF]]> } [[VLD1XN]], ptr [[__RET]] @@ -25,7 +25,7 @@ float16x4x2_t test_vld1_f16_x2(float16_t const *a) { // CHECK-LABEL: @test_vld1_f16_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float16x4x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.float16x4x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float16x4x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float16x4x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x [[HALF:half|i16]]>, <4 x [[HALF]]>, <4 x [[HALF]]> } @llvm.{{aarch64.neon.ld1x3.v4f16.p0|arm.neon.vld1x3.v4i16.p0}}(ptr %a) // CHECK: store { <4 x [[HALF]]>, <4 x [[HALF]]>, <4 x [[HALF]]> } [[VLD1XN]], ptr [[__RET]] @@ -39,7 +39,7 @@ float16x4x3_t test_vld1_f16_x3(float16_t const *a) { // CHECK-LABEL: @test_vld1_f16_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float16x4x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.float16x4x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float16x4x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float16x4x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x [[HALF:half|i16]]>, <4 x [[HALF]]>, <4 x [[HALF]]>, <4 x [[HALF]]> } @llvm.{{aarch64.neon.ld1x4.v4f16.p0|arm.neon.vld1x4.v4i16.p0}}(ptr %a) // CHECK: store { <4 x [[HALF]]>, <4 x [[HALF]]>, <4 x [[HALF]]>, <4 x [[HALF]]> } [[VLD1XN]], ptr [[__RET]] @@ -53,7 +53,7 @@ float16x4x4_t test_vld1_f16_x4(float16_t const *a) { // CHECK-LABEL: @test_vld1_f32_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float32x2x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.float32x2x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float32x2x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float32x2x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <2 x float>, <2 x float> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v2f32.p0(ptr %a) // CHECK: store { <2 x float>, <2 x float> } [[VLD1XN]], ptr [[__RET]] @@ -67,7 +67,7 @@ float32x2x2_t test_vld1_f32_x2(float32_t const *a) { // CHECK-LABEL: @test_vld1_f32_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float32x2x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.float32x2x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float32x2x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float32x2x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <2 x float>, <2 x float>, <2 x float> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v2f32.p0(ptr %a) // CHECK: store { <2 x float>, <2 x float>, <2 x float> } [[VLD1XN]], ptr [[__RET]] @@ -80,7 +80,7 @@ float32x2x3_t test_vld1_f32_x3(float32_t const *a) { // CHECK-LABEL: @test_vld1_f32_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float32x2x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.float32x2x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float32x2x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float32x2x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <2 x float>, <2 x float>, <2 x float>, <2 x float> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v2f32.p0(ptr %a) // CHECK: store { <2 x float>, <2 x float>, <2 x float>, <2 x float> } [[VLD1XN]], ptr [[__RET]] @@ -94,7 +94,7 @@ float32x2x4_t test_vld1_f32_x4(float32_t const *a) { // CHECK-LABEL: @test_vld1_p16_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly16x4x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.poly16x4x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly16x4x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly16x4x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x i16>, <4 x i16> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v4i16.p0(ptr %a) // CHECK: store { <4 x i16>, <4 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -108,7 +108,7 @@ poly16x4x2_t test_vld1_p16_x2(poly16_t const *a) { // CHECK-LABEL: @test_vld1_p16_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly16x4x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.poly16x4x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly16x4x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly16x4x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x i16>, <4 x i16>, <4 x i16> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v4i16.p0(ptr %a) // CHECK: store { <4 x i16>, <4 x i16>, <4 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -122,7 +122,7 @@ poly16x4x3_t test_vld1_p16_x3(poly16_t const *a) { // CHECK-LABEL: @test_vld1_p16_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly16x4x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.poly16x4x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly16x4x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly16x4x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v4i16.p0(ptr %a) // CHECK: store { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -136,7 +136,7 @@ poly16x4x4_t test_vld1_p16_x4(poly16_t const *a) { // CHECK-LABEL: @test_vld1_p8_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly8x8x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.poly8x8x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly8x8x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly8x8x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <8 x i8>, <8 x i8> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v8i8.p0(ptr %a) // CHECK: store { <8 x i8>, <8 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -150,7 +150,7 @@ poly8x8x2_t test_vld1_p8_x2(poly8_t const *a) { // CHECK-LABEL: @test_vld1_p8_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly8x8x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.poly8x8x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly8x8x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly8x8x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <8 x i8>, <8 x i8>, <8 x i8> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v8i8.p0(ptr %a) // CHECK: store { <8 x i8>, <8 x i8>, <8 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -164,7 +164,7 @@ poly8x8x3_t test_vld1_p8_x3(poly8_t const *a) { // CHECK-LABEL: @test_vld1_p8_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly8x8x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.poly8x8x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly8x8x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly8x8x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v8i8.p0(ptr %a) // CHECK: store { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -178,7 +178,7 @@ poly8x8x4_t test_vld1_p8_x4(poly8_t const *a) { // CHECK-LABEL: @test_vld1_s16_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int16x4x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int16x4x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int16x4x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int16x4x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x i16>, <4 x i16> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v4i16.p0(ptr %a) // CHECK: store { <4 x i16>, <4 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -192,7 +192,7 @@ int16x4x2_t test_vld1_s16_x2(int16_t const *a) { // CHECK-LABEL: @test_vld1_s16_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int16x4x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int16x4x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int16x4x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int16x4x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x i16>, <4 x i16>, <4 x i16> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v4i16.p0(ptr %a) // CHECK: store { <4 x i16>, <4 x i16>, <4 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -206,7 +206,7 @@ int16x4x3_t test_vld1_s16_x3(int16_t const *a) { // CHECK-LABEL: @test_vld1_s16_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int16x4x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int16x4x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int16x4x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int16x4x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v4i16.p0(ptr %a) // CHECK: store { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -220,7 +220,7 @@ int16x4x4_t test_vld1_s16_x4(int16_t const *a) { // CHECK-LABEL: @test_vld1_s32_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int32x2x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int32x2x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int32x2x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int32x2x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <2 x i32>, <2 x i32> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v2i32.p0(ptr %a) // CHECK: store { <2 x i32>, <2 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -234,7 +234,7 @@ int32x2x2_t test_vld1_s32_x2(int32_t const *a) { // CHECK-LABEL: @test_vld1_s32_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int32x2x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int32x2x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int32x2x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int32x2x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v2i32.p0(ptr %a) // CHECK: store { <2 x i32>, <2 x i32>, <2 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -248,7 +248,7 @@ int32x2x3_t test_vld1_s32_x3(int32_t const *a) { // CHECK-LABEL: @test_vld1_s32_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int32x2x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int32x2x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int32x2x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int32x2x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v2i32.p0(ptr %a) // CHECK: store { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -262,7 +262,7 @@ int32x2x4_t test_vld1_s32_x4(int32_t const *a) { // CHECK-LABEL: @test_vld1_s64_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int64x1x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int64x1x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int64x1x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int64x1x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <1 x i64>, <1 x i64> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v1i64.p0(ptr %a) // CHECK: store { <1 x i64>, <1 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -276,7 +276,7 @@ int64x1x2_t test_vld1_s64_x2(int64_t const *a) { // CHECK-LABEL: @test_vld1_s64_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int64x1x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int64x1x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int64x1x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int64x1x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <1 x i64>, <1 x i64>, <1 x i64> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v1i64.p0(ptr %a) // CHECK: store { <1 x i64>, <1 x i64>, <1 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -290,7 +290,7 @@ int64x1x3_t test_vld1_s64_x3(int64_t const *a) { // CHECK-LABEL: @test_vld1_s64_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int64x1x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int64x1x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int64x1x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int64x1x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v1i64.p0(ptr %a) // CHECK: store { <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -304,7 +304,7 @@ int64x1x4_t test_vld1_s64_x4(int64_t const *a) { // CHECK-LABEL: @test_vld1_s8_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int8x8x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int8x8x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int8x8x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int8x8x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <8 x i8>, <8 x i8> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v8i8.p0(ptr %a) // CHECK: store { <8 x i8>, <8 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -318,7 +318,7 @@ int8x8x2_t test_vld1_s8_x2(int8_t const *a) { // CHECK-LABEL: @test_vld1_s8_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int8x8x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int8x8x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int8x8x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int8x8x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <8 x i8>, <8 x i8>, <8 x i8> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v8i8.p0(ptr %a) // CHECK: store { <8 x i8>, <8 x i8>, <8 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -332,7 +332,7 @@ int8x8x3_t test_vld1_s8_x3(int8_t const *a) { // CHECK-LABEL: @test_vld1_s8_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int8x8x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.int8x8x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int8x8x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int8x8x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v8i8.p0(ptr %a) // CHECK: store { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -346,7 +346,7 @@ int8x8x4_t test_vld1_s8_x4(int8_t const *a) { // CHECK-LABEL: @test_vld1_u16_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint16x4x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint16x4x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint16x4x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint16x4x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x i16>, <4 x i16> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v4i16.p0(ptr %a) // CHECK: store { <4 x i16>, <4 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -360,7 +360,7 @@ uint16x4x2_t test_vld1_u16_x2(uint16_t const *a) { // CHECK-LABEL: @test_vld1_u16_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint16x4x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint16x4x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint16x4x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint16x4x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x i16>, <4 x i16>, <4 x i16> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v4i16.p0(ptr %a) // CHECK: store { <4 x i16>, <4 x i16>, <4 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -374,7 +374,7 @@ uint16x4x3_t test_vld1_u16_x3(uint16_t const *a) { // CHECK-LABEL: @test_vld1_u16_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint16x4x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint16x4x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint16x4x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint16x4x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v4i16.p0(ptr %a) // CHECK: store { <4 x i16>, <4 x i16>, <4 x i16>, <4 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -388,7 +388,7 @@ uint16x4x4_t test_vld1_u16_x4(uint16_t const *a) { // CHECK-LABEL: @test_vld1_u32_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint32x2x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint32x2x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint32x2x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint32x2x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <2 x i32>, <2 x i32> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v2i32.p0(ptr %a) // CHECK: store { <2 x i32>, <2 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -402,7 +402,7 @@ uint32x2x2_t test_vld1_u32_x2(uint32_t const *a) { // CHECK-LABEL: @test_vld1_u32_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint32x2x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint32x2x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint32x2x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint32x2x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v2i32.p0(ptr %a) // CHECK: store { <2 x i32>, <2 x i32>, <2 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -416,7 +416,7 @@ uint32x2x3_t test_vld1_u32_x3(uint32_t const *a) { // CHECK-LABEL: @test_vld1_u32_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint32x2x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint32x2x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint32x2x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint32x2x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v2i32.p0(ptr %a) // CHECK: store { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -430,7 +430,7 @@ uint32x2x4_t test_vld1_u32_x4(uint32_t const *a) { // CHECK-LABEL: @test_vld1_u64_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint64x1x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint64x1x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint64x1x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint64x1x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <1 x i64>, <1 x i64> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v1i64.p0(ptr %a) // CHECK: store { <1 x i64>, <1 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -444,7 +444,7 @@ uint64x1x2_t test_vld1_u64_x2(uint64_t const *a) { // CHECK-LABEL: @test_vld1_u64_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint64x1x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint64x1x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint64x1x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint64x1x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <1 x i64>, <1 x i64>, <1 x i64> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v1i64.p0(ptr %a) // CHECK: store { <1 x i64>, <1 x i64>, <1 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -458,7 +458,7 @@ uint64x1x3_t test_vld1_u64_x3(uint64_t const *a) { // CHECK-LABEL: @test_vld1_u64_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint64x1x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint64x1x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint64x1x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint64x1x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v1i64.p0(ptr %a) // CHECK: store { <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -472,7 +472,7 @@ uint64x1x4_t test_vld1_u64_x4(uint64_t const *a) { // CHECK-LABEL: @test_vld1_u8_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint8x8x2_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint8x8x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint8x8x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint8x8x2_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <8 x i8>, <8 x i8> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v8i8.p0(ptr %a) // CHECK: store { <8 x i8>, <8 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -486,7 +486,7 @@ uint8x8x2_t test_vld1_u8_x2(uint8_t const *a) { // CHECK-LABEL: @test_vld1_u8_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint8x8x3_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint8x8x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint8x8x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint8x8x3_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <8 x i8>, <8 x i8>, <8 x i8> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v8i8.p0(ptr %a) // CHECK: store { <8 x i8>, <8 x i8>, <8 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -500,7 +500,7 @@ uint8x8x3_t test_vld1_u8_x3(uint8_t const *a) { // CHECK-LABEL: @test_vld1_u8_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint8x8x4_t, align 8 -// CHECK-A32: ptr noalias sret(%struct.uint8x8x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint8x8x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint8x8x4_t, align 8 // CHECK: [[VLD1XN:%.*]] = call { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v8i8.p0(ptr %a) // CHECK: store { <8 x i8>, <8 x i8>, <8 x i8>, <8 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -514,7 +514,7 @@ uint8x8x4_t test_vld1_u8_x4(uint8_t const *a) { // CHECK-LABEL: @test_vld1q_f16_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float16x8x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.float16x8x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float16x8x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float16x8x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x [[HALF:half|i16]]>, <8 x [[HALF]]> } @llvm.{{aarch64.neon.ld1x2.v8f16.p0|arm.neon.vld1x2.v8i16.p0}}(ptr %a) // CHECK: store { <8 x [[HALF]]>, <8 x [[HALF]]> } [[VLD1XN]], ptr [[__RET]] @@ -528,7 +528,7 @@ float16x8x2_t test_vld1q_f16_x2(float16_t const *a) { // CHECK-LABEL: @test_vld1q_f16_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float16x8x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.float16x8x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float16x8x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float16x8x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x [[HALF:half|i16]]>, <8 x [[HALF]]>, <8 x [[HALF]]> } @llvm.{{aarch64.neon.ld1x3.v8f16.p0|arm.neon.vld1x3.v8i16.p0}}(ptr %a) // CHECK: store { <8 x [[HALF]]>, <8 x [[HALF]]>, <8 x [[HALF]]> } [[VLD1XN]], ptr [[__RET]] @@ -542,7 +542,7 @@ float16x8x3_t test_vld1q_f16_x3(float16_t const *a) { // CHECK-LABEL: @test_vld1q_f16_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float16x8x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.float16x8x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float16x8x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float16x8x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x [[HALF:half|i16]]>, <8 x [[HALF]]>, <8 x [[HALF]]>, <8 x [[HALF]]> } @llvm.{{aarch64.neon.ld1x4.v8f16.p0|arm.neon.vld1x4.v8i16.p0}}(ptr %a) // CHECK: store { <8 x [[HALF]]>, <8 x [[HALF]]>, <8 x [[HALF]]>, <8 x [[HALF]]> } [[VLD1XN]], ptr [[__RET]] @@ -556,7 +556,7 @@ float16x8x4_t test_vld1q_f16_x4(float16_t const *a) { // CHECK-LABEL: @test_vld1q_f32_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float32x4x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.float32x4x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float32x4x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float32x4x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <4 x float>, <4 x float> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v4f32.p0(ptr %a) // CHECK: store { <4 x float>, <4 x float> } [[VLD1XN]], ptr [[__RET]] @@ -570,7 +570,7 @@ float32x4x2_t test_vld1q_f32_x2(float32_t const *a) { // CHECK-LABEL: @test_vld1q_f32_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float32x4x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.float32x4x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float32x4x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float32x4x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <4 x float>, <4 x float>, <4 x float> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v4f32.p0(ptr %a) // CHECK: store { <4 x float>, <4 x float>, <4 x float> } [[VLD1XN]], ptr [[__RET]] @@ -584,7 +584,7 @@ float32x4x3_t test_vld1q_f32_x3(float32_t const *a) { // CHECK-LABEL: @test_vld1q_f32_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.float32x4x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.float32x4x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.float32x4x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.float32x4x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <4 x float>, <4 x float>, <4 x float>, <4 x float> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v4f32.p0(ptr %a) // CHECK: store { <4 x float>, <4 x float>, <4 x float>, <4 x float> } [[VLD1XN]], ptr [[__RET]] @@ -598,7 +598,7 @@ float32x4x4_t test_vld1q_f32_x4(float32_t const *a) { // CHECK-LABEL: @test_vld1q_p16_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly16x8x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.poly16x8x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly16x8x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly16x8x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x i16>, <8 x i16> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v8i16.p0(ptr %a) // CHECK: store { <8 x i16>, <8 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -612,7 +612,7 @@ poly16x8x2_t test_vld1q_p16_x2(poly16_t const *a) { // CHECK-LABEL: @test_vld1q_p16_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly16x8x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.poly16x8x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly16x8x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly16x8x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x i16>, <8 x i16>, <8 x i16> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v8i16.p0(ptr %a) // CHECK: store { <8 x i16>, <8 x i16>, <8 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -626,7 +626,7 @@ poly16x8x3_t test_vld1q_p16_x3(poly16_t const *a) { // CHECK-LABEL: @test_vld1q_p16_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly16x8x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.poly16x8x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly16x8x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly16x8x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v8i16.p0(ptr %a) // CHECK: store { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -640,7 +640,7 @@ poly16x8x4_t test_vld1q_p16_x4(poly16_t const *a) { // CHECK-LABEL: @test_vld1q_p8_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly8x16x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.poly8x16x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly8x16x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly8x16x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v16i8.p0(ptr %a) // CHECK: store { <16 x i8>, <16 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -654,7 +654,7 @@ poly8x16x2_t test_vld1q_p8_x2(poly8_t const *a) { // CHECK-LABEL: @test_vld1q_p8_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly8x16x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.poly8x16x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly8x16x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly8x16x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <16 x i8>, <16 x i8>, <16 x i8> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v16i8.p0(ptr %a) // CHECK: store { <16 x i8>, <16 x i8>, <16 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -668,7 +668,7 @@ poly8x16x3_t test_vld1q_p8_x3(poly8_t const *a) { // CHECK-LABEL: @test_vld1q_p8_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.poly8x16x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.poly8x16x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.poly8x16x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.poly8x16x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v16i8.p0(ptr %a) // CHECK: store { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -682,7 +682,7 @@ poly8x16x4_t test_vld1q_p8_x4(poly8_t const *a) { // CHECK-LABEL: @test_vld1q_s16_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int16x8x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int16x8x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int16x8x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int16x8x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x i16>, <8 x i16> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v8i16.p0(ptr %a) // CHECK: store { <8 x i16>, <8 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -696,7 +696,7 @@ int16x8x2_t test_vld1q_s16_x2(int16_t const *a) { // CHECK-LABEL: @test_vld1q_s16_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int16x8x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int16x8x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int16x8x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int16x8x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x i16>, <8 x i16>, <8 x i16> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v8i16.p0(ptr %a) // CHECK: store { <8 x i16>, <8 x i16>, <8 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -710,7 +710,7 @@ int16x8x3_t test_vld1q_s16_x3(int16_t const *a) { // CHECK-LABEL: @test_vld1q_s16_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int16x8x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int16x8x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int16x8x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int16x8x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v8i16.p0(ptr %a) // CHECK: store { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -724,7 +724,7 @@ int16x8x4_t test_vld1q_s16_x4(int16_t const *a) { // CHECK-LABEL: @test_vld1q_s32_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int32x4x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int32x4x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int32x4x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int32x4x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v4i32.p0(ptr %a) // CHECK: store { <4 x i32>, <4 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -738,7 +738,7 @@ int32x4x2_t test_vld1q_s32_x2(int32_t const *a) { // CHECK-LABEL: @test_vld1q_s32_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int32x4x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int32x4x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int32x4x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int32x4x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v4i32.p0(ptr %a) // CHECK: store { <4 x i32>, <4 x i32>, <4 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -752,7 +752,7 @@ int32x4x3_t test_vld1q_s32_x3(int32_t const *a) { // CHECK-LABEL: @test_vld1q_s32_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int32x4x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int32x4x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int32x4x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int32x4x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v4i32.p0(ptr %a) // CHECK: store { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -766,7 +766,7 @@ int32x4x4_t test_vld1q_s32_x4(int32_t const *a) { // CHECK-LABEL: @test_vld1q_s64_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int64x2x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int64x2x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int64x2x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int64x2x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <2 x i64>, <2 x i64> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v2i64.p0(ptr %a) // CHECK: store { <2 x i64>, <2 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -780,7 +780,7 @@ int64x2x2_t test_vld1q_s64_x2(int64_t const *a) { // CHECK-LABEL: @test_vld1q_s64_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int64x2x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int64x2x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int64x2x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int64x2x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <2 x i64>, <2 x i64>, <2 x i64> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v2i64.p0(ptr %a) // CHECK: store { <2 x i64>, <2 x i64>, <2 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -794,7 +794,7 @@ int64x2x3_t test_vld1q_s64_x3(int64_t const *a) { // CHECK-LABEL: @test_vld1q_s64_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int64x2x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int64x2x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int64x2x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int64x2x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v2i64.p0(ptr %a) // CHECK: store { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -808,7 +808,7 @@ int64x2x4_t test_vld1q_s64_x4(int64_t const *a) { // CHECK-LABEL: @test_vld1q_s8_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int8x16x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int8x16x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int8x16x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int8x16x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v16i8.p0(ptr %a) // CHECK: store { <16 x i8>, <16 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -822,7 +822,7 @@ int8x16x2_t test_vld1q_s8_x2(int8_t const *a) { // CHECK-LABEL: @test_vld1q_s8_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int8x16x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int8x16x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int8x16x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int8x16x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <16 x i8>, <16 x i8>, <16 x i8> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v16i8.p0(ptr %a) // CHECK: store { <16 x i8>, <16 x i8>, <16 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -836,7 +836,7 @@ int8x16x3_t test_vld1q_s8_x3(int8_t const *a) { // CHECK-LABEL: @test_vld1q_s8_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.int8x16x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.int8x16x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.int8x16x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.int8x16x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v16i8.p0(ptr %a) // CHECK: store { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -850,7 +850,7 @@ int8x16x4_t test_vld1q_s8_x4(int8_t const *a) { // CHECK-LABEL: @test_vld1q_u16_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint16x8x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint16x8x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint16x8x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint16x8x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x i16>, <8 x i16> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v8i16.p0(ptr %a) // CHECK: store { <8 x i16>, <8 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -864,7 +864,7 @@ uint16x8x2_t test_vld1q_u16_x2(uint16_t const *a) { // CHECK-LABEL: @test_vld1q_u16_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint16x8x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint16x8x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint16x8x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint16x8x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x i16>, <8 x i16>, <8 x i16> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v8i16.p0(ptr %a) // CHECK: store { <8 x i16>, <8 x i16>, <8 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -878,7 +878,7 @@ uint16x8x3_t test_vld1q_u16_x3(uint16_t const *a) { // CHECK-LABEL: @test_vld1q_u16_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint16x8x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint16x8x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint16x8x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint16x8x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v8i16.p0(ptr %a) // CHECK: store { <8 x i16>, <8 x i16>, <8 x i16>, <8 x i16> } [[VLD1XN]], ptr [[__RET]] @@ -892,7 +892,7 @@ uint16x8x4_t test_vld1q_u16_x4(uint16_t const *a) { // CHECK-LABEL: @test_vld1q_u32_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint32x4x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint32x4x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint32x4x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint32x4x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v4i32.p0(ptr %a) // CHECK: store { <4 x i32>, <4 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -906,7 +906,7 @@ uint32x4x2_t test_vld1q_u32_x2(uint32_t const *a) { // CHECK-LABEL: @test_vld1q_u32_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint32x4x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint32x4x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint32x4x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint32x4x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v4i32.p0(ptr %a) // CHECK: store { <4 x i32>, <4 x i32>, <4 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -920,7 +920,7 @@ uint32x4x3_t test_vld1q_u32_x3(uint32_t const *a) { // CHECK-LABEL: @test_vld1q_u32_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint32x4x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint32x4x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint32x4x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint32x4x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v4i32.p0(ptr %a) // CHECK: store { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } [[VLD1XN]], ptr [[__RET]] @@ -934,7 +934,7 @@ uint32x4x4_t test_vld1q_u32_x4(uint32_t const *a) { // CHECK-LABEL: @test_vld1q_u64_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint64x2x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint64x2x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint64x2x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint64x2x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <2 x i64>, <2 x i64> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v2i64.p0(ptr %a) // CHECK: store { <2 x i64>, <2 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -948,7 +948,7 @@ uint64x2x2_t test_vld1q_u64_x2(uint64_t const *a) { // CHECK-LABEL: @test_vld1q_u64_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint64x2x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint64x2x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint64x2x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint64x2x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <2 x i64>, <2 x i64>, <2 x i64> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v2i64.p0(ptr %a) // CHECK: store { <2 x i64>, <2 x i64>, <2 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -962,7 +962,7 @@ uint64x2x3_t test_vld1q_u64_x3(uint64_t const *a) { // CHECK-LABEL: @test_vld1q_u64_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint64x2x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint64x2x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint64x2x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint64x2x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v2i64.p0(ptr %a) // CHECK: store { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } [[VLD1XN]], ptr [[__RET]] @@ -976,7 +976,7 @@ uint64x2x4_t test_vld1q_u64_x4(uint64_t const *a) { // CHECK-LABEL: @test_vld1q_u8_x2( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint8x16x2_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint8x16x2_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint8x16x2_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint8x16x2_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <16 x i8>, <16 x i8> } @llvm.{{aarch64.neon.ld1x2|arm.neon.vld1x2}}.v16i8.p0(ptr %a) // CHECK: store { <16 x i8>, <16 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -990,7 +990,7 @@ uint8x16x2_t test_vld1q_u8_x2(uint8_t const *a) { // CHECK-LABEL: @test_vld1q_u8_x3( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint8x16x3_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint8x16x3_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint8x16x3_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint8x16x3_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <16 x i8>, <16 x i8>, <16 x i8> } @llvm.{{aarch64.neon.ld1x3|arm.neon.vld1x3}}.v16i8.p0(ptr %a) // CHECK: store { <16 x i8>, <16 x i8>, <16 x i8> } [[VLD1XN]], ptr [[__RET]] @@ -1004,7 +1004,7 @@ uint8x16x3_t test_vld1q_u8_x3(uint8_t const *a) { // CHECK-LABEL: @test_vld1q_u8_x4( // CHECK-A64: [[RETVAL:%.*]] = alloca %struct.uint8x16x4_t, align 16 -// CHECK-A32: ptr noalias sret(%struct.uint8x16x4_t) align 8 [[RETVAL:%.*]], +// CHECK-A32: ptr dead_on_unwind noalias writable sret(%struct.uint8x16x4_t) align 8 [[RETVAL:%.*]], // CHECK: [[__RET:%.*]] = alloca %struct.uint8x16x4_t, align {{16|8}} // CHECK: [[VLD1XN:%.*]] = call { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } @llvm.{{aarch64.neon.ld1x4|arm.neon.vld1x4}}.v16i8.p0(ptr %a) // CHECK: store { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } [[VLD1XN]], ptr [[__RET]] diff --git a/clang/test/CodeGen/arm-swiftcall.c b/clang/test/CodeGen/arm-swiftcall.c index 12bccb5087c8e..9fa607a968ccf 100644 --- a/clang/test/CodeGen/arm-swiftcall.c +++ b/clang/test/CodeGen/arm-swiftcall.c @@ -22,7 +22,7 @@ SWIFTCALL int indirect_result_2(OUT int *arg0, OUT float *arg1) { __builtin_unr typedef struct { char array[1024]; } struct_reallybig; SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); } -// CHECK-LABEL: define{{.*}} void @indirect_result_3(ptr noalias sret(%struct.struct_reallybig) {{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}) +// CHECK-LABEL: define{{.*}} void @indirect_result_3(ptr dead_on_unwind noalias writable sret(%struct.struct_reallybig) {{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}, ptr noalias align 4 dereferenceable(4){{.*}}) SWIFTCALL void context_1(CONTEXT void *self) {} // CHECK-LABEL: define{{.*}} void @context_1(ptr swiftself @@ -258,7 +258,7 @@ typedef struct { } struct_big_1; TEST(struct_big_1) -// CHECK-LABEL: define{{.*}} void @return_struct_big_1({{.*}} noalias sret({{.*}}) +// CHECK-LABEL: define{{.*}} void @return_struct_big_1({{.*}} dead_on_unwind noalias writable sret({{.*}}) // Should not be byval. // CHECK-LABEL: define{{.*}} void @take_struct_big_1(ptr{{( %.*)?}}) @@ -553,7 +553,7 @@ typedef struct { double d4; } struct_d5; TEST(struct_d5) -// CHECK: define{{.*}} swiftcc void @return_struct_d5(ptr noalias sret([[STRUCT5:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_d5(ptr dead_on_unwind noalias writable sret([[STRUCT5:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_d5(ptr typedef struct { @@ -703,7 +703,7 @@ typedef struct { long long l2; } struct_l3; TEST(struct_l3) -// CHECK: define{{.*}} swiftcc void @return_struct_l3(ptr noalias sret([[STRUCT:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_l3(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_l3(ptr typedef struct { @@ -713,7 +713,7 @@ typedef struct { long long l3; } struct_l4; TEST(struct_l4) -// CHECK: define{{.*}} swiftcc void @return_struct_l4(ptr noalias sret([[STRUCT:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_l4(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_l4(ptr typedef struct { @@ -724,7 +724,7 @@ typedef struct { long long l4; } struct_l5; TEST(struct_l5) -// CHECK: define{{.*}} swiftcc void @return_struct_l5(ptr noalias sret([[STRUCT5:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_l5(ptr dead_on_unwind noalias writable sret([[STRUCT5:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_l5(ptr typedef struct { @@ -769,7 +769,7 @@ typedef struct { char16 c4; } struct_vc5; TEST(struct_vc5) -// CHECK: define{{.*}} swiftcc void @return_struct_vc5(ptr noalias sret([[STRUCT:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vc5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_vc5(ptr typedef struct { @@ -814,7 +814,7 @@ typedef struct { short8 c4; } struct_vs5; TEST(struct_vs5) -// CHECK: define{{.*}} swiftcc void @return_struct_vs5(ptr noalias sret([[STRUCT:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vs5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_vs5(ptr typedef struct { @@ -859,7 +859,7 @@ typedef struct { int4 c4; } struct_vi5; TEST(struct_vi5) -// CHECK: define{{.*}} swiftcc void @return_struct_vi5(ptr noalias sret([[STRUCT:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vi5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_vi5(ptr typedef struct { @@ -887,7 +887,7 @@ typedef struct { long2 c4; } struct_vl5; TEST(struct_vl5) -// CHECK: define{{.*}} swiftcc void @return_struct_vl5(ptr noalias sret([[STRUCT:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vl5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_vl5(ptr typedef struct { @@ -915,7 +915,7 @@ typedef struct { double2 c4; } struct_vd5; TEST(struct_vd5) -// CHECK: define{{.*}} swiftcc void @return_struct_vd5(ptr noalias sret([[STRUCT:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vd5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_vd5(ptr typedef struct { @@ -939,7 +939,7 @@ typedef struct { double4 c2; } struct_vd43; TEST(struct_vd43) -// CHECK: define{{.*}} swiftcc void @return_struct_vd43(ptr noalias sret([[STRUCT:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vd43(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_vd43(ptr typedef struct { @@ -975,7 +975,7 @@ typedef struct { float4 c4; } struct_vf5; TEST(struct_vf5) -// CHECK: define{{.*}} swiftcc void @return_struct_vf5(ptr noalias sret([[STRUCT:%.*]]) +// CHECK: define{{.*}} swiftcc void @return_struct_vf5(ptr dead_on_unwind noalias writable sret([[STRUCT:%.*]]) // CHECK: define{{.*}} swiftcc void @take_struct_vf5(ptr typedef struct { diff --git a/clang/test/CodeGen/arm-varargs.c b/clang/test/CodeGen/arm-varargs.c index 17330262e6ad6..f754c7f52e590 100644 --- a/clang/test/CodeGen/arm-varargs.c +++ b/clang/test/CodeGen/arm-varargs.c @@ -23,7 +23,7 @@ struct bigstruct { }; struct bigstruct simple_struct(void) { -// CHECK-LABEL: define{{.*}} void @simple_struct(ptr noalias sret(%struct.bigstruct) align 4 %agg.result) +// CHECK-LABEL: define{{.*}} void @simple_struct(ptr dead_on_unwind noalias writable sret(%struct.bigstruct) align 4 %agg.result) return va_arg(the_list, struct bigstruct); // CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4 // CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 40 @@ -38,7 +38,7 @@ struct aligned_bigstruct { }; struct aligned_bigstruct simple_aligned_struct(void) { -// CHECK-LABEL: define{{.*}} void @simple_aligned_struct(ptr noalias sret(%struct.aligned_bigstruct) align 8 %agg.result) +// CHECK-LABEL: define{{.*}} void @simple_aligned_struct(ptr dead_on_unwind noalias writable sret(%struct.aligned_bigstruct) align 8 %agg.result) return va_arg(the_list, struct aligned_bigstruct); // CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4 // CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7 @@ -66,7 +66,7 @@ struct hfa { }; struct hfa simple_hfa(void) { -// CHECK-LABEL: define{{.*}} void @simple_hfa(ptr noalias sret(%struct.hfa) align 4 %agg.result) +// CHECK-LABEL: define{{.*}} void @simple_hfa(ptr dead_on_unwind noalias writable sret(%struct.hfa) align 4 %agg.result) return va_arg(the_list, struct hfa); // CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4 // CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 8 @@ -159,7 +159,7 @@ typedef struct __attribute__((aligned(16))) { int val; } overaligned_int_struct; overaligned_int_struct overaligned_int_struct_test(void) { -// CHECK-LABEL: define{{.*}} void @overaligned_int_struct_test(ptr noalias sret(%struct.overaligned_int_struct) align 16 %agg.result) +// CHECK-LABEL: define{{.*}} void @overaligned_int_struct_test(ptr dead_on_unwind noalias writable sret(%struct.overaligned_int_struct) align 16 %agg.result) return va_arg(the_list, overaligned_int_struct); // CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4 // CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 16 @@ -172,7 +172,7 @@ typedef struct __attribute__((packed,aligned(2))) { long long val; } underaligned_long_long_struct; underaligned_long_long_struct underaligned_long_long_struct_test(void) { -// CHECK-LABEL: define{{.*}} void @underaligned_long_long_struct_test(ptr noalias sret(%struct.underaligned_long_long_struct) align 2 %agg.result) +// CHECK-LABEL: define{{.*}} void @underaligned_long_long_struct_test(ptr dead_on_unwind noalias writable sret(%struct.underaligned_long_long_struct) align 2 %agg.result) return va_arg(the_list, underaligned_long_long_struct); // CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4 // CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 8 @@ -185,7 +185,7 @@ typedef struct __attribute__((aligned(16))) { long long val; } overaligned_long_long_struct; overaligned_long_long_struct overaligned_long_long_struct_test(void) { -// CHECK-LABEL: define{{.*}} void @overaligned_long_long_struct_test(ptr noalias sret(%struct.overaligned_long_long_struct) align 16 %agg.result) +// CHECK-LABEL: define{{.*}} void @overaligned_long_long_struct_test(ptr dead_on_unwind noalias writable sret(%struct.overaligned_long_long_struct) align 16 %agg.result) return va_arg(the_list, overaligned_long_long_struct); // CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4 // CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7 @@ -219,7 +219,7 @@ typedef struct { int val __attribute__((aligned(16))); } overaligned_int_struct_member; overaligned_int_struct_member overaligned_int_struct_member_test(void) { -// CHECK-LABEL: define{{.*}} void @overaligned_int_struct_member_test(ptr noalias sret(%struct.overaligned_int_struct_member) align 16 %agg.result) +// CHECK-LABEL: define{{.*}} void @overaligned_int_struct_member_test(ptr dead_on_unwind noalias writable sret(%struct.overaligned_int_struct_member) align 16 %agg.result) return va_arg(the_list, overaligned_int_struct_member); // CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4 // CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7 @@ -234,7 +234,7 @@ typedef struct { long long val __attribute__((packed,aligned(2))); } underaligned_long_long_struct_member; underaligned_long_long_struct_member underaligned_long_long_struct_member_test(void) { -// CHECK-LABEL: define{{.*}} void @underaligned_long_long_struct_member_test(ptr noalias sret(%struct.underaligned_long_long_struct_member) align 2 %agg.result) +// CHECK-LABEL: define{{.*}} void @underaligned_long_long_struct_member_test(ptr dead_on_unwind noalias writable sret(%struct.underaligned_long_long_struct_member) align 2 %agg.result) return va_arg(the_list, underaligned_long_long_struct_member); // CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4 // CHECK: [[NEXT:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 8 @@ -247,7 +247,7 @@ typedef struct { long long val __attribute__((aligned(16))); } overaligned_long_long_struct_member; overaligned_long_long_struct_member overaligned_long_long_struct_member_test(void) { -// CHECK-LABEL: define{{.*}} void @overaligned_long_long_struct_member_test(ptr noalias sret(%struct.overaligned_long_long_struct_member) align 16 %agg.result) +// CHECK-LABEL: define{{.*}} void @overaligned_long_long_struct_member_test(ptr dead_on_unwind noalias writable sret(%struct.overaligned_long_long_struct_member) align 16 %agg.result) return va_arg(the_list, overaligned_long_long_struct_member); // CHECK: [[CUR:%[a-z0-9._]+]] = load ptr, ptr @the_list, align 4 // CHECK: [[CUR_INT_ADD:%[a-z0-9._]+]] = getelementptr inbounds i8, ptr [[CUR]], i32 7 diff --git a/clang/test/CodeGen/arm-vector-arguments.c b/clang/test/CodeGen/arm-vector-arguments.c index a92e5a84798bc..0e3abfb7e5a06 100644 --- a/clang/test/CodeGen/arm-vector-arguments.c +++ b/clang/test/CodeGen/arm-vector-arguments.c @@ -9,7 +9,7 @@ #include -// CHECK: define{{.*}} void @f0(ptr noalias sret(%struct.int8x16x2_t) align 16 %agg.result, <16 x i8> noundef %{{.*}}, <16 x i8> noundef %{{.*}}) +// CHECK: define{{.*}} void @f0(ptr dead_on_unwind noalias writable sret(%struct.int8x16x2_t) align 16 %agg.result, <16 x i8> noundef %{{.*}}, <16 x i8> noundef %{{.*}}) int8x16x2_t f0(int8x16_t a0, int8x16_t a1) { return vzipq_s8(a0, a1); } @@ -25,7 +25,7 @@ typedef float T_float32x16 __attribute__ ((__vector_size__ (64))); T_float32x2 f1_0(T_float32x2 a0) { return a0; } // CHECK: define{{.*}} <4 x float> @f1_1(<4 x float> noundef %{{.*}}) T_float32x4 f1_1(T_float32x4 a0) { return a0; } -// CHECK: define{{.*}} void @f1_2(ptr noalias sret(<8 x float>) align 32 %{{.*}}, <8 x float> noundef %{{.*}}) +// CHECK: define{{.*}} void @f1_2(ptr dead_on_unwind noalias writable sret(<8 x float>) align 32 %{{.*}}, <8 x float> noundef %{{.*}}) T_float32x8 f1_2(T_float32x8 a0) { return a0; } -// CHECK: define{{.*}} void @f1_3(ptr noalias sret(<16 x float>) align 64 %{{.*}}, <16 x float> noundef %{{.*}}) +// CHECK: define{{.*}} void @f1_3(ptr dead_on_unwind noalias writable sret(<16 x float>) align 64 %{{.*}}, <16 x float> noundef %{{.*}}) T_float32x16 f1_3(T_float32x16 a0) { return a0; } diff --git a/clang/test/CodeGen/arm-vfp16-arguments.c b/clang/test/CodeGen/arm-vfp16-arguments.c index 59120c1cc7f14..da034626024f8 100644 --- a/clang/test/CodeGen/arm-vfp16-arguments.c +++ b/clang/test/CodeGen/arm-vfp16-arguments.c @@ -71,6 +71,6 @@ void test_hfa(hfa_t a) {} hfa_t ghfa; hfa_t test_ret_hfa(void) { return ghfa; } -// CHECK-SOFT: define{{.*}} void @test_ret_hfa(ptr noalias nocapture writeonly sret(%struct.hfa_t) align 8 %agg.result) +// CHECK-SOFT: define{{.*}} void @test_ret_hfa(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.hfa_t) align 8 %agg.result) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @test_ret_hfa() // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.hfa_t @test_ret_hfa() diff --git a/clang/test/CodeGen/arm-vfp16-arguments2.cpp b/clang/test/CodeGen/arm-vfp16-arguments2.cpp index 2ba0c0d349ab7..6221e85e856b4 100644 --- a/clang/test/CodeGen/arm-vfp16-arguments2.cpp +++ b/clang/test/CodeGen/arm-vfp16-arguments2.cpp @@ -37,27 +37,27 @@ struct S5 : B1 { B1 M[1]; }; -// CHECK-SOFT: define{{.*}} void @_Z2f12S1(ptr noalias nocapture writeonly sret(%struct.S1) align 8 %agg.result, [2 x i64] %s1.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f12S1(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S1) align 8 %agg.result, [2 x i64] %s1.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f12S1([2 x <2 x i32>] returned %s1.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S1 @_Z2f12S1(%struct.S1 returned %s1.coerce) struct S1 f1(struct S1 s1) { return s1; } -// CHECK-SOFT: define{{.*}} void @_Z2f22S2(ptr noalias nocapture writeonly sret(%struct.S2) align 8 %agg.result, [4 x i32] %s2.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f22S2(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S2) align 8 %agg.result, [4 x i32] %s2.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f22S2([2 x <2 x i32>] returned %s2.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S2 @_Z2f22S2(%struct.S2 returned %s2.coerce) struct S2 f2(struct S2 s2) { return s2; } -// CHECK-SOFT: define{{.*}} void @_Z2f32S3(ptr noalias nocapture writeonly sret(%struct.S3) align 8 %agg.result, [2 x i64] %s3.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f32S3(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S3) align 8 %agg.result, [2 x i64] %s3.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f32S3([2 x <2 x i32>] returned %s3.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S3 @_Z2f32S3(%struct.S3 returned %s3.coerce) struct S3 f3(struct S3 s3) { return s3; } -// CHECK-SOFT: define{{.*}} void @_Z2f42S4(ptr noalias nocapture writeonly sret(%struct.S4) align 8 %agg.result, [2 x i64] %s4.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f42S4(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S4) align 8 %agg.result, [2 x i64] %s4.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f42S4([2 x <2 x i32>] returned %s4.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S4 @_Z2f42S4(%struct.S4 returned %s4.coerce) struct S4 f4(struct S4 s4) { return s4; } -// CHECK-SOFT: define{{.*}} void @_Z2f52S5(ptr noalias nocapture writeonly sret(%struct.S5) align 8 %agg.result, [2 x i64] %s5.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f52S5(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S5) align 8 %agg.result, [2 x i64] %s5.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc %struct.S5 @_Z2f52S5(%struct.S5 returned %s5.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S5 @_Z2f52S5(%struct.S5 returned %s5.coerce) struct S5 f5(struct S5 s5) { return s5; } diff --git a/clang/test/CodeGen/arm64-arguments.c b/clang/test/CodeGen/arm64-arguments.c index caa71ced0a8ae..8ed9d952f80c8 100644 --- a/clang/test/CodeGen/arm64-arguments.c +++ b/clang/test/CodeGen/arm64-arguments.c @@ -226,9 +226,9 @@ T_float32x2 f1_0(T_float32x2 a0) { return a0; } // CHECK: define{{.*}} <4 x float> @f1_1(<4 x float> noundef %{{.*}}) T_float32x4 f1_1(T_float32x4 a0) { return a0; } // Vector with length bigger than 16-byte is illegal and is passed indirectly. -// CHECK: define{{.*}} void @f1_2(ptr noalias sret(<8 x float>) align 16 %{{.*}}, ptr noundef %0) +// CHECK: define{{.*}} void @f1_2(ptr dead_on_unwind noalias writable sret(<8 x float>) align 16 %{{.*}}, ptr noundef %0) T_float32x8 f1_2(T_float32x8 a0) { return a0; } -// CHECK: define{{.*}} void @f1_3(ptr noalias sret(<16 x float>) align 16 %{{.*}}, ptr noundef %0) +// CHECK: define{{.*}} void @f1_3(ptr dead_on_unwind noalias writable sret(<16 x float>) align 16 %{{.*}}, ptr noundef %0) T_float32x16 f1_3(T_float32x16 a0) { return a0; } // Testing alignment with aggregates: HFA, aggregates with size <= 16 bytes and diff --git a/clang/test/CodeGen/arm64-microsoft-arguments.cpp b/clang/test/CodeGen/arm64-microsoft-arguments.cpp index a9ae6911b16e3..e8309888dcfe2 100644 --- a/clang/test/CodeGen/arm64-microsoft-arguments.cpp +++ b/clang/test/CodeGen/arm64-microsoft-arguments.cpp @@ -28,8 +28,8 @@ S2 f2() { } // Pass and return for type size > 16 bytes. -// CHECK: define {{.*}} void @{{.*}}f3{{.*}}(ptr noalias sret(%struct.S3) align 4 %agg.result) -// CHECK: call void {{.*}}func3{{.*}}(ptr sret(%struct.S3) align 4 %agg.result, ptr noundef %agg.tmp) +// CHECK: define {{.*}} void @{{.*}}f3{{.*}}(ptr dead_on_unwind noalias writable sret(%struct.S3) align 4 %agg.result) +// CHECK: call void {{.*}}func3{{.*}}(ptr dead_on_unwind writable sret(%struct.S3) align 4 %agg.result, ptr noundef %agg.tmp) struct S3 { int a[5]; }; @@ -42,8 +42,8 @@ S3 f3() { // Pass and return aggregate (of size < 16 bytes) with non-trivial destructor. // Passed directly but returned indirectly. -// CHECK: define {{.*}} void {{.*}}f4{{.*}}(ptr inreg noalias sret(%struct.S4) align 4 %agg.result) -// CHECK: call void {{.*}}func4{{.*}}(ptr inreg sret(%struct.S4) align 4 %agg.result, [2 x i64] %0) +// CHECK: define {{.*}} void {{.*}}f4{{.*}}(ptr dead_on_unwind inreg noalias writable sret(%struct.S4) align 4 %agg.result) +// CHECK: call void {{.*}}func4{{.*}}(ptr dead_on_unwind inreg writable sret(%struct.S4) align 4 %agg.result, [2 x i64] %0) struct S4 { int a[3]; ~S4(); @@ -56,8 +56,8 @@ S4 f4() { } // Pass and return from instance method called from instance method. -// CHECK: define {{.*}} void @{{.*}}bar@Q1{{.*}}(ptr {{[^,]*}} %this, ptr inreg noalias sret(%class.P1) align 1 %agg.result) -// CHECK: call void {{.*}}foo@P1{{.*}}(ptr noundef{{[^,]*}} %ref.tmp, ptr inreg sret(%class.P1) align 1 %agg.result, i8 %0) +// CHECK: define {{.*}} void @{{.*}}bar@Q1{{.*}}(ptr {{[^,]*}} %this, ptr dead_on_unwind inreg noalias writable sret(%class.P1) align 1 %agg.result) +// CHECK: call void {{.*}}foo@P1{{.*}}(ptr noundef{{[^,]*}} %ref.tmp, ptr dead_on_unwind inreg writable sret(%class.P1) align 1 %agg.result, i8 %0) class P1 { public: @@ -76,7 +76,7 @@ P1 Q1::bar() { // Pass and return from instance method called from free function. // CHECK: define {{.*}} void {{.*}}bar{{.*}}() -// CHECK: call void {{.*}}foo@P2{{.*}}(ptr noundef{{[^,]*}} %ref.tmp, ptr inreg sret(%class.P2) align 1 %retval, i8 %0) +// CHECK: call void {{.*}}foo@P2{{.*}}(ptr noundef{{[^,]*}} %ref.tmp, ptr dead_on_unwind inreg writable sret(%class.P2) align 1 %retval, i8 %0) class P2 { public: P2 foo(P2 x); @@ -89,8 +89,8 @@ P2 bar() { // Pass and return an object with a user-provided constructor (passed directly, // returned indirectly) -// CHECK: define {{.*}} void @{{.*}}f5{{.*}}(ptr inreg noalias sret(%struct.S5) align 4 %agg.result) -// CHECK: call void {{.*}}func5{{.*}}(ptr inreg sret(%struct.S5) align 4 %agg.result, i64 {{.*}}) +// CHECK: define {{.*}} void @{{.*}}f5{{.*}}(ptr dead_on_unwind inreg noalias writable sret(%struct.S5) align 4 %agg.result) +// CHECK: call void {{.*}}func5{{.*}}(ptr dead_on_unwind inreg writable sret(%struct.S5) align 4 %agg.result, i64 {{.*}}) struct S5 { S5(); int x; @@ -146,8 +146,8 @@ struct S8 { int y; }; -// CHECK: define {{.*}} void {{.*}}?f8{{.*}}(ptr inreg noalias sret(%struct.S8) align 4 {{.*}}) -// CHECK: call void {{.*}}func8{{.*}}(ptr inreg sret(%struct.S8) align 4 {{.*}}, i64 {{.*}}) +// CHECK: define {{.*}} void {{.*}}?f8{{.*}}(ptr dead_on_unwind inreg noalias writable sret(%struct.S8) align 4 {{.*}}) +// CHECK: call void {{.*}}func8{{.*}}(ptr dead_on_unwind inreg writable sret(%struct.S8) align 4 {{.*}}, i64 {{.*}}) S8 func8(S8 x); S8 f8() { S8 x; @@ -157,8 +157,8 @@ S8 f8() { // Pass and return an object with a non-trivial copy-assignment operator and // a trivial copy constructor (passed directly, returned indirectly) -// CHECK: define {{.*}} void @"?f9@@YA?AUS9@@XZ"(ptr inreg noalias sret(%struct.S9) align 4 {{.*}}) -// CHECK: call void {{.*}}func9{{.*}}(ptr inreg sret(%struct.S9) align 4 {{.*}}, i64 {{.*}}) +// CHECK: define {{.*}} void @"?f9@@YA?AUS9@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.S9) align 4 {{.*}}) +// CHECK: call void {{.*}}func9{{.*}}(ptr dead_on_unwind inreg writable sret(%struct.S9) align 4 {{.*}}, i64 {{.*}}) struct S9 { S9& operator=(const S9&); int x; @@ -174,8 +174,8 @@ S9 f9() { // Pass and return an object with a base class (passed directly, returned // indirectly). -// CHECK: define dso_local void {{.*}}f10{{.*}}(ptr inreg noalias sret(%struct.S10) align 4 {{.*}}) -// CHECK: call void {{.*}}func10{{.*}}(ptr inreg sret(%struct.S10) align 4 {{.*}}, [2 x i64] {{.*}}) +// CHECK: define dso_local void {{.*}}f10{{.*}}(ptr dead_on_unwind inreg noalias writable sret(%struct.S10) align 4 {{.*}}) +// CHECK: call void {{.*}}func10{{.*}}(ptr dead_on_unwind inreg writable sret(%struct.S10) align 4 {{.*}}, [2 x i64] {{.*}}) struct S10 : public S1 { int x; }; @@ -189,8 +189,8 @@ S10 f10() { // Pass and return a non aggregate object exceeding > 128 bits (passed // indirectly, returned indirectly) -// CHECK: define dso_local void {{.*}}f11{{.*}}(ptr inreg noalias sret(%struct.S11) align 8 {{.*}}) -// CHECK: call void {{.*}}func11{{.*}}(ptr inreg sret(%struct.S11) align 8 {{.*}}, ptr {{.*}}) +// CHECK: define dso_local void {{.*}}f11{{.*}}(ptr dead_on_unwind inreg noalias writable sret(%struct.S11) align 8 {{.*}}) +// CHECK: call void {{.*}}func11{{.*}}(ptr dead_on_unwind inreg writable sret(%struct.S11) align 8 {{.*}}, ptr {{.*}}) struct S11 { virtual void f(); int a[5]; diff --git a/clang/test/CodeGen/arm64_32.c b/clang/test/CodeGen/arm64_32.c index 31d94c610704a..f7473610d30d9 100644 --- a/clang/test/CodeGen/arm64_32.c +++ b/clang/test/CodeGen/arm64_32.c @@ -27,4 +27,4 @@ long double LongDoubleVar = 0.0; typedef float __attribute__((ext_vector_type(16))) v16f32; v16f32 func(v16f32 in) { return in; } -// CHECK: define{{.*}} void @func(ptr noalias sret(<16 x float>) align 16 {{%.*}}, <16 x float> noundef {{%.*}}) +// CHECK: define{{.*}} void @func(ptr dead_on_unwind noalias writable sret(<16 x float>) align 16 {{%.*}}, <16 x float> noundef {{%.*}}) diff --git a/clang/test/CodeGen/armv7k-abi.c b/clang/test/CodeGen/armv7k-abi.c index e070d5a9c7041..fd18dafa7d03f 100644 --- a/clang/test/CodeGen/armv7k-abi.c +++ b/clang/test/CodeGen/armv7k-abi.c @@ -42,7 +42,7 @@ typedef struct { // CHECK: define{{.*}} void @big_struct_indirect(ptr noundef %b) void big_struct_indirect(BigStruct b) {} -// CHECK: define{{.*}} void @return_big_struct_indirect(ptr noalias sret +// CHECK: define{{.*}} void @return_big_struct_indirect(ptr dead_on_unwind noalias writable sret BigStruct return_big_struct_indirect() {} // Structs smaller than 16 bytes should be passed directly, and coerced to diff --git a/clang/test/CodeGen/attr-noundef.cpp b/clang/test/CodeGen/attr-noundef.cpp index a2aa7e313f0e8..d236b35fdfd7d 100644 --- a/clang/test/CodeGen/attr-noundef.cpp +++ b/clang/test/CodeGen/attr-noundef.cpp @@ -26,7 +26,7 @@ struct NoCopy { }; NoCopy ret_nocopy() { return {}; } void pass_nocopy(NoCopy e) {} -// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr noalias sret({{[^)]+}}) align 4 % +// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 % // CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr noundef % struct Huge { @@ -34,7 +34,7 @@ struct Huge { }; Huge ret_huge() { return {}; } void pass_huge(Huge h) {} -// CHECK: [[DEF]] void @{{.*}}ret_huge{{.*}}(ptr noalias sret({{[^)]+}}) align 4 % +// CHECK: [[DEF]] void @{{.*}}ret_huge{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 % // CHECK: [[DEF]] void @{{.*}}pass_huge{{.*}}(ptr noundef } // namespace check_structs @@ -58,7 +58,7 @@ union NoCopy { }; NoCopy ret_nocopy() { return {}; } void pass_nocopy(NoCopy e) {} -// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr noalias sret({{[^)]+}}) align 4 % +// CHECK: [[DEF]] void @{{.*}}ret_nocopy{{.*}}(ptr dead_on_unwind noalias writable sret({{[^)]+}}) align 4 % // CHECK: [[DEF]] void @{{.*}}pass_nocopy{{.*}}(ptr noundef % } // namespace check_unions diff --git a/clang/test/CodeGen/blocks.c b/clang/test/CodeGen/blocks.c index 469cf7cb89a2c..8f947fcdfccb2 100644 --- a/clang/test/CodeGen/blocks.c +++ b/clang/test/CodeGen/blocks.c @@ -15,7 +15,7 @@ struct s0 { int a[64]; }; -// CHECK: define internal void @__f2_block_invoke(ptr noalias sret(%struct.s0) align 4 {{%.*}}, ptr noundef {{%.*}}, ptr noundef byval(%struct.s0) align 4 {{.*}}) +// CHECK: define internal void @__f2_block_invoke(ptr dead_on_unwind noalias writable sret(%struct.s0) align 4 {{%.*}}, ptr noundef {{%.*}}, ptr noundef byval(%struct.s0) align 4 {{.*}}) struct s0 f2(struct s0 a0) { return ^(struct s0 a1){ return a1; }(a0); } diff --git a/clang/test/CodeGen/c11atomics-ios.c b/clang/test/CodeGen/c11atomics-ios.c index af489811edc58..bcb6519ab0dc8 100644 --- a/clang/test/CodeGen/c11atomics-ios.c +++ b/clang/test/CodeGen/c11atomics-ios.c @@ -178,7 +178,7 @@ void testPromotedStruct(_Atomic(PS) *fp) { } PS test_promoted_load(_Atomic(PS) *addr) { - // CHECK-LABEL: @test_promoted_load(ptr noalias sret(%struct.PS) align 2 %agg.result, ptr noundef %addr) + // CHECK-LABEL: @test_promoted_load(ptr dead_on_unwind noalias writable sret(%struct.PS) align 2 %agg.result, ptr noundef %addr) // CHECK: [[ADDR_ARG:%.*]] = alloca ptr, align 4 // CHECK: [[ATOMIC_RES:%.*]] = alloca { %struct.PS, [2 x i8] }, align 8 // CHECK: store ptr %addr, ptr [[ADDR_ARG]], align 4 @@ -209,7 +209,7 @@ void test_promoted_store(_Atomic(PS) *addr, PS *val) { } PS test_promoted_exchange(_Atomic(PS) *addr, PS *val) { - // CHECK-LABEL: @test_promoted_exchange(ptr noalias sret(%struct.PS) align 2 %agg.result, ptr noundef %addr, ptr noundef %val) + // CHECK-LABEL: @test_promoted_exchange(ptr dead_on_unwind noalias writable sret(%struct.PS) align 2 %agg.result, ptr noundef %addr, ptr noundef %val) // CHECK: [[ADDR_ARG:%.*]] = alloca ptr, align 4 // CHECK: [[VAL_ARG:%.*]] = alloca ptr, align 4 // CHECK: [[NONATOMIC_TMP:%.*]] = alloca %struct.PS, align 2 diff --git a/clang/test/CodeGen/c11atomics.c b/clang/test/CodeGen/c11atomics.c index 773ed41991f78..dd1f52f70ae09 100644 --- a/clang/test/CodeGen/c11atomics.c +++ b/clang/test/CodeGen/c11atomics.c @@ -338,7 +338,7 @@ void testPromotedStruct(_Atomic(PS) *fp) { } PS test_promoted_load(_Atomic(PS) *addr) { - // CHECK-LABEL: @test_promoted_load(ptr noalias sret(%struct.PS) align 2 %agg.result, ptr noundef %addr) + // CHECK-LABEL: @test_promoted_load(ptr dead_on_unwind noalias writable sret(%struct.PS) align 2 %agg.result, ptr noundef %addr) // CHECK: [[ADDR_ARG:%.*]] = alloca ptr, align 4 // CHECK: [[ATOMIC_RES:%.*]] = alloca { %struct.PS, [2 x i8] }, align 8 // CHECK: store ptr %addr, ptr [[ADDR_ARG]], align 4 @@ -368,7 +368,7 @@ void test_promoted_store(_Atomic(PS) *addr, PS *val) { } PS test_promoted_exchange(_Atomic(PS) *addr, PS *val) { - // CHECK-LABEL: @test_promoted_exchange(ptr noalias sret(%struct.PS) align 2 %agg.result, ptr noundef %addr, ptr noundef %val) + // CHECK-LABEL: @test_promoted_exchange(ptr dead_on_unwind noalias writable sret(%struct.PS) align 2 %agg.result, ptr noundef %addr, ptr noundef %val) // CHECK: [[ADDR_ARG:%.*]] = alloca ptr, align 4 // CHECK: [[VAL_ARG:%.*]] = alloca ptr, align 4 // CHECK: [[NONATOMIC_TMP:%.*]] = alloca %struct.PS, align 2 diff --git a/clang/test/CodeGen/ext-int-cc.c b/clang/test/CodeGen/ext-int-cc.c index bcf29fc1309de..001e866d34b45 100644 --- a/clang/test/CodeGen/ext-int-cc.c +++ b/clang/test/CodeGen/ext-int-cc.c @@ -226,104 +226,104 @@ _BitInt(64) ReturnPassing2(void){} _BitInt(127) ReturnPassing3(void){} // LIN64: define{{.*}} { i64, i64 } @ReturnPassing3( -// WIN64: define dso_local void @ReturnPassing3(ptr noalias sret -// LIN32: define{{.*}} void @ReturnPassing3(ptr noalias sret -// WIN32: define dso_local void @ReturnPassing3(ptr noalias sret -// NACL: define{{.*}} void @ReturnPassing3(ptr noalias sret +// WIN64: define dso_local void @ReturnPassing3(ptr dead_on_unwind noalias writable sret +// LIN32: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret +// WIN32: define dso_local void @ReturnPassing3(ptr dead_on_unwind noalias writable sret +// NACL: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret // NVPTX/64 makes the intentional choice to put all return values direct, even // large structures, so we do the same here. // NVPTX64: define{{.*}} i127 @ReturnPassing3( // NVPTX: define{{.*}} i127 @ReturnPassing3( // SPARCV9: define{{.*}} i127 @ReturnPassing3( -// SPARC: define{{.*}} void @ReturnPassing3(ptr noalias sret +// SPARC: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret // MIPS64: define{{.*}} i127 @ReturnPassing3( -// MIPS: define{{.*}} void @ReturnPassing3(ptr noalias sret -// SPIR64: define{{.*}} spir_func void @ReturnPassing3(ptr noalias sret -// SPIR: define{{.*}} spir_func void @ReturnPassing3(ptr noalias sret -// HEX: define{{.*}} void @ReturnPassing3(ptr noalias sret -// LANAI: define{{.*}} void @ReturnPassing3(ptr noalias sret -// R600: define{{.*}} void @ReturnPassing3(ptr addrspace(5) noalias sret -// ARC: define{{.*}} void @ReturnPassing3(ptr noalias sret -// XCORE: define{{.*}} void @ReturnPassing3(ptr noalias sret +// MIPS: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret +// SPIR64: define{{.*}} spir_func void @ReturnPassing3(ptr dead_on_unwind noalias writable sret +// SPIR: define{{.*}} spir_func void @ReturnPassing3(ptr dead_on_unwind noalias writable sret +// HEX: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret +// LANAI: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret +// R600: define{{.*}} void @ReturnPassing3(ptr addrspace(5) dead_on_unwind noalias writable sret +// ARC: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret +// XCORE: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret // RISCV64: define{{.*}} i127 @ReturnPassing3( -// RISCV32: define{{.*}} void @ReturnPassing3(ptr noalias sret +// RISCV32: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret // WASM: define{{.*}} i127 @ReturnPassing3( -// SYSTEMZ: define{{.*}} void @ReturnPassing3(ptr noalias sret +// SYSTEMZ: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret // PPC64: define{{.*}} i127 @ReturnPassing3( -// PPC32: define{{.*}} void @ReturnPassing3(ptr noalias sret +// PPC32: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret // AARCH64: define{{.*}} i127 @ReturnPassing3( // AARCH64DARWIN: define{{.*}} i127 @ReturnPassing3( -// ARM: define{{.*}} arm_aapcscc void @ReturnPassing3(ptr noalias sret +// ARM: define{{.*}} arm_aapcscc void @ReturnPassing3(ptr dead_on_unwind noalias writable sret // LA64: define{{.*}} i127 @ReturnPassing3( -// LA32: define{{.*}} void @ReturnPassing3(ptr noalias sret +// LA32: define{{.*}} void @ReturnPassing3(ptr dead_on_unwind noalias writable sret _BitInt(128) ReturnPassing4(void){} // LIN64: define{{.*}} { i64, i64 } @ReturnPassing4( -// WIN64: define dso_local void @ReturnPassing4(ptr noalias sret -// LIN32: define{{.*}} void @ReturnPassing4(ptr noalias sret -// WIN32: define dso_local void @ReturnPassing4(ptr noalias sret -// NACL: define{{.*}} void @ReturnPassing4(ptr noalias sret +// WIN64: define dso_local void @ReturnPassing4(ptr dead_on_unwind noalias writable sret +// LIN32: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret +// WIN32: define dso_local void @ReturnPassing4(ptr dead_on_unwind noalias writable sret +// NACL: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret // NVPTX64: define{{.*}} i128 @ReturnPassing4( // NVPTX: define{{.*}} i128 @ReturnPassing4( // SPARCV9: define{{.*}} i128 @ReturnPassing4( -// SPARC: define{{.*}} void @ReturnPassing4(ptr noalias sret +// SPARC: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret // MIPS64: define{{.*}} i128 @ReturnPassing4( -// MIPS: define{{.*}} void @ReturnPassing4(ptr noalias sret -// SPIR64: define{{.*}} spir_func void @ReturnPassing4(ptr noalias sret -// SPIR: define{{.*}} spir_func void @ReturnPassing4(ptr noalias sret -// HEX: define{{.*}} void @ReturnPassing4(ptr noalias sret -// LANAI: define{{.*}} void @ReturnPassing4(ptr noalias sret -// R600: define{{.*}} void @ReturnPassing4(ptr addrspace(5) noalias sret -// ARC: define{{.*}} void @ReturnPassing4(ptr noalias sret -// XCORE: define{{.*}} void @ReturnPassing4(ptr noalias sret +// MIPS: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret +// SPIR64: define{{.*}} spir_func void @ReturnPassing4(ptr dead_on_unwind noalias writable sret +// SPIR: define{{.*}} spir_func void @ReturnPassing4(ptr dead_on_unwind noalias writable sret +// HEX: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret +// LANAI: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret +// R600: define{{.*}} void @ReturnPassing4(ptr addrspace(5) dead_on_unwind noalias writable sret +// ARC: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret +// XCORE: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret // RISCV64: define{{.*}} i128 @ReturnPassing4( -// RISCV32: define{{.*}} void @ReturnPassing4(ptr noalias sret +// RISCV32: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret // WASM: define{{.*}} i128 @ReturnPassing4( -// SYSTEMZ: define{{.*}} void @ReturnPassing4(ptr noalias sret +// SYSTEMZ: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret // PPC64: define{{.*}} i128 @ReturnPassing4( -// PPC32: define{{.*}} void @ReturnPassing4(ptr noalias sret +// PPC32: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret // AARCH64: define{{.*}} i128 @ReturnPassing4( // AARCH64DARWIN: define{{.*}} i128 @ReturnPassing4( -// ARM: define{{.*}} arm_aapcscc void @ReturnPassing4(ptr noalias sret +// ARM: define{{.*}} arm_aapcscc void @ReturnPassing4(ptr dead_on_unwind noalias writable sret // LA64: define{{.*}} i128 @ReturnPassing4( -// LA32: define{{.*}} void @ReturnPassing4(ptr noalias sret +// LA32: define{{.*}} void @ReturnPassing4(ptr dead_on_unwind noalias writable sret #if __BITINT_MAXWIDTH__ > 128 _BitInt(129) ReturnPassing5(void){} -// LIN64: define{{.*}} void @ReturnPassing5(ptr noalias sret -// WIN64: define dso_local void @ReturnPassing5(ptr noalias sret -// LIN32: define{{.*}} void @ReturnPassing5(ptr noalias sret -// WIN32: define dso_local void @ReturnPassing5(ptr noalias sret -// NACL-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret +// LIN64: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// WIN64: define dso_local void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// LIN32: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// WIN32: define dso_local void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// NACL-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret // NVPTX64-NOT: define{{.*}} i129 @ReturnPassing5( // NVPTX-NOT: define{{.*}} i129 @ReturnPassing5( // SPARCV9-NOT: define{{.*}} i129 @ReturnPassing5( -// SPARC-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// MIPS64-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// MIPS-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// SPIR64-NOT: define{{.*}} spir_func void @ReturnPassing5(ptr noalias sret -// SPIR-NOT: define{{.*}} spir_func void @ReturnPassing5(ptr noalias sret -// HEX-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// LANAI-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret +// SPARC-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// MIPS64-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// MIPS-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// SPIR64-NOT: define{{.*}} spir_func void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// SPIR-NOT: define{{.*}} spir_func void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// HEX-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// LANAI-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret // R600-NOT: define{{.*}} void @ReturnPassing5(ptr addrspace(5) noalias sret -// ARC-NOT: define{{.*}} void @ReturnPassing5(ptr inreg noalias sret -// XCORE-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// RISCV64-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// RISCV32-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// WASM-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// SYSTEMZ-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// PPC64-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// PPC32-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// AARCH64-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// AARCH64DARWIN-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// ARM-NOT: define{{.*}} arm_aapcscc void @ReturnPassing5(ptr noalias sret -// LA64-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret -// LA32-NOT: define{{.*}} void @ReturnPassing5(ptr noalias sret +// ARC-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind inreg noalias writable sret +// XCORE-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// RISCV64-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// RISCV32-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// WASM-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// SYSTEMZ-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// PPC64-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// PPC32-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// AARCH64-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// AARCH64DARWIN-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// ARM-NOT: define{{.*}} arm_aapcscc void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// LA64-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret +// LA32-NOT: define{{.*}} void @ReturnPassing5(ptr dead_on_unwind noalias writable sret // SparcV9 is odd in that it has a return-size limit of 256, not 128 or 64 // like other platforms, so test to make sure this behavior will still work. _BitInt(256) ReturnPassing6(void) {} // SPARCV9-NOT: define{{.*}} i256 @ReturnPassing6( _BitInt(257) ReturnPassing7(void) {} -// SPARCV9-NOT: define{{.*}} void @ReturnPassing7(ptr noalias sret +// SPARCV9-NOT: define{{.*}} void @ReturnPassing7(ptr dead_on_unwind noalias writable sret #endif diff --git a/clang/test/CodeGen/isfpclass.c b/clang/test/CodeGen/isfpclass.c index 430f5d94211f1..6633db88f71a8 100644 --- a/clang/test/CodeGen/isfpclass.c +++ b/clang/test/CodeGen/isfpclass.c @@ -160,7 +160,7 @@ int4 check_isfpclass_nan_strict_v4f32(float4 x) { } // CHECK-LABEL: define dso_local void @check_isfpclass_nan_v4f64 -// CHECK-SAME: (ptr noalias nocapture writeonly sret(<4 x i64>) align 16 [[AGG_RESULT:%.*]], ptr nocapture noundef readonly [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { +// CHECK-SAME: (ptr dead_on_unwind noalias nocapture writable writeonly sret(<4 x i64>) align 16 [[AGG_RESULT:%.*]], ptr nocapture noundef readonly [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[X:%.*]] = load <4 x double>, ptr [[TMP0]], align 16, !tbaa [[TBAA2:![0-9]+]] // CHECK-NEXT: [[TMP1:%.*]] = fcmp uno <4 x double> [[X]], zeroinitializer diff --git a/clang/test/CodeGen/lanai-arguments.c b/clang/test/CodeGen/lanai-arguments.c index bc291faa867f5..bfd3b41a91eb2 100644 --- a/clang/test/CodeGen/lanai-arguments.c +++ b/clang/test/CodeGen/lanai-arguments.c @@ -16,7 +16,7 @@ void f1(s1 i) {} typedef struct { int cc; } s2; -// CHECK: define{{.*}} void @f2(ptr noalias sret(%struct.s2) align 4 %agg.result) +// CHECK: define{{.*}} void @f2(ptr dead_on_unwind noalias writable sret(%struct.s2) align 4 %agg.result) s2 f2(void) { s2 foo; return foo; @@ -26,7 +26,7 @@ typedef struct { int cc; int dd; } s3; -// CHECK: define{{.*}} void @f3(ptr noalias sret(%struct.s3) align 4 %agg.result) +// CHECK: define{{.*}} void @f3(ptr dead_on_unwind noalias writable sret(%struct.s3) align 4 %agg.result) s3 f3(void) { s3 foo; return foo; diff --git a/clang/test/CodeGen/mcu-struct-return.c b/clang/test/CodeGen/mcu-struct-return.c index 218f9734c9c32..38a9bc2a36bfe 100644 --- a/clang/test/CodeGen/mcu-struct-return.c +++ b/clang/test/CodeGen/mcu-struct-return.c @@ -42,7 +42,7 @@ struct S1 bar1(void) { return s1; } struct S2 bar2(void) { return s2; } struct S1 bar3(union U1 u) { return s1; } // CHECK: define{{.*}} void @foo1() -// CHECK: define{{.*}} void @foo2(ptr noalias sret([[UNION2_TYPE]]) align 4 %{{.+}}) +// CHECK: define{{.*}} void @foo2(ptr dead_on_unwind noalias writable sret([[UNION2_TYPE]]) align 4 %{{.+}}) // CHECK: define{{.*}} i32 @foo3() // CHECK: define{{.*}} void @bar1() // CHECK: define{{.*}} i32 @bar2() @@ -62,7 +62,7 @@ void run(void) { // CHECK: [[Y1:%.+]] = alloca [[STRUCT1_TYPE]] // CHECK: [[Y2:%.+]] = alloca [[STRUCT2_TYPE]] // CHECK: call void @foo1() - // CHECK: call void @foo2(ptr sret([[UNION2_TYPE]]) align 4 [[X2]]) + // CHECK: call void @foo2(ptr dead_on_unwind writable sret([[UNION2_TYPE]]) align 4 [[X2]]) // CHECK: {{.+}} = call i32 @foo3() // CHECK: call void @bar1() // CHECK: {{.+}} = call i32 @bar2() diff --git a/clang/test/CodeGen/mingw-long-double.c b/clang/test/CodeGen/mingw-long-double.c index a50f8f0b3b633..4be97526f9631 100644 --- a/clang/test/CodeGen/mingw-long-double.c +++ b/clang/test/CodeGen/mingw-long-double.c @@ -32,15 +32,15 @@ long double TestLD(long double x) { return x * x; } // GNU32: define dso_local x86_fp80 @TestLD(x86_fp80 noundef %x) -// GNU64: define dso_local void @TestLD(ptr noalias sret(x86_fp80) align 16 %agg.result, ptr noundef %0) +// GNU64: define dso_local void @TestLD(ptr dead_on_unwind noalias writable sret(x86_fp80) align 16 %agg.result, ptr noundef %0) // MSC64: define dso_local double @TestLD(double noundef %x) long double _Complex TestLDC(long double _Complex x) { return x * x; } -// GNU32: define dso_local void @TestLDC(ptr noalias sret({ x86_fp80, x86_fp80 }) align 4 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 4 %x) -// GNU64: define dso_local void @TestLDC(ptr noalias sret({ x86_fp80, x86_fp80 }) align 16 %agg.result, ptr noundef %x) -// MSC64: define dso_local void @TestLDC(ptr noalias sret({ double, double }) align 8 %agg.result, ptr noundef %x) +// GNU32: define dso_local void @TestLDC(ptr dead_on_unwind noalias writable sret({ x86_fp80, x86_fp80 }) align 4 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 4 %x) +// GNU64: define dso_local void @TestLDC(ptr dead_on_unwind noalias writable sret({ x86_fp80, x86_fp80 }) align 16 %agg.result, ptr noundef %x) +// MSC64: define dso_local void @TestLDC(ptr dead_on_unwind noalias writable sret({ double, double }) align 8 %agg.result, ptr noundef %x) // GNU32: declare dso_local void @__mulxc3 // GNU64: declare dso_local void @__mulxc3 diff --git a/clang/test/CodeGen/mips-vector-return.c b/clang/test/CodeGen/mips-vector-return.c index b6da2af2ffd66..d2103d1def745 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 noalias nocapture writeonly sret +// O32-LABEL: define{{.*}} void @test_v4sf(ptr dead_on_unwind noalias nocapture writable writeonly 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 noalias nocapture writeonly sret -// N64-LABEL: define{{.*}} void @test_v4df(ptr noalias nocapture writeonly sret +// 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 v4df test_v4df(double a) { return (v4df){0.0, a, 0.0, 0.0}; } diff --git a/clang/test/CodeGen/mips-zero-sized-struct.c b/clang/test/CodeGen/mips-zero-sized-struct.c index 12bd9abf6cf4c..b40ff59f73fb2 100644 --- a/clang/test/CodeGen/mips-zero-sized-struct.c +++ b/clang/test/CodeGen/mips-zero-sized-struct.c @@ -19,7 +19,7 @@ // RUN: %clang_cc1 -triple mipsisa64r6-unknown-linux-gnuabi64 -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s // RUN: %clang_cc1 -triple mipsisa64r6el-unknown-linux-gnuabi64 -S -emit-llvm -o - %s | FileCheck -check-prefix=N64 %s -// O32: define{{.*}} void @fn28(ptr noalias sret(%struct.T2) align 1 %agg.result, i8 noundef signext %arg0) +// O32: define{{.*}} void @fn28(ptr dead_on_unwind noalias writable sret(%struct.T2) align 1 %agg.result, i8 noundef signext %arg0) // N32: define{{.*}} void @fn28(i8 noundef signext %arg0) // N64: define{{.*}} void @fn28(i8 noundef signext %arg0) diff --git a/clang/test/CodeGen/mips64-nontrivial-return.cpp b/clang/test/CodeGen/mips64-nontrivial-return.cpp index 0987dcaf355dd..a8fbf4622f803 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 noalias nocapture writeonly sret +// CHECK: _Z4foo1v(ptr dead_on_unwind noalias nocapture writable writeonly sret D foo1(void) { return gd0; diff --git a/clang/test/CodeGen/mips64-padding-arg.c b/clang/test/CodeGen/mips64-padding-arg.c index 7fda45f75098f..038103b1df3aa 100644 --- a/clang/test/CodeGen/mips64-padding-arg.c +++ b/clang/test/CodeGen/mips64-padding-arg.c @@ -33,9 +33,9 @@ void foo3(int a0, long double a1) { // Insert padding after hidden argument. // -// N64-LABEL: define{{.*}} void @foo5(ptr noalias sret(%struct.S0) align 16 %agg.result, i64 %0, fp128 noundef %a0) -// N64: call void @foo6(ptr sret(%struct.S0) align 16 %agg.result, i32 noundef signext 1, i32 noundef signext 2, i64 undef, fp128 noundef %a0) -// N64: declare void @foo6(ptr sret(%struct.S0) align 16, i32 noundef signext, i32 noundef signext, i64, fp128 noundef) +// N64-LABEL: define{{.*}} void @foo5(ptr dead_on_unwind noalias writable sret(%struct.S0) align 16 %agg.result, i64 %0, fp128 noundef %a0) +// N64: call void @foo6(ptr dead_on_unwind writable sret(%struct.S0) align 16 %agg.result, i32 noundef signext 1, i32 noundef signext 2, i64 undef, fp128 noundef %a0) +// N64: declare void @foo6(ptr dead_on_unwind writable sret(%struct.S0) align 16, i32 noundef signext, i32 noundef signext, i64, fp128 noundef) extern S0 foo6(int, int, long double); diff --git a/clang/test/CodeGen/ms_abi.c b/clang/test/CodeGen/ms_abi.c index adc5094267cbd..0fe1741cf9a0a 100644 --- a/clang/test/CodeGen/ms_abi.c +++ b/clang/test/CodeGen/ms_abi.c @@ -141,7 +141,7 @@ struct i128 { }; __attribute__((ms_abi)) struct i128 f7(struct i128 a) { - // WIN64: define dso_local void @f7(ptr noalias sret(%struct.i128) align 8 %agg.result, ptr noundef %a) - // FREEBSD: define{{.*}} win64cc void @f7(ptr noalias sret(%struct.i128) align 8 %agg.result, ptr noundef %a) + // WIN64: define dso_local void @f7(ptr dead_on_unwind noalias writable sret(%struct.i128) align 8 %agg.result, ptr noundef %a) + // FREEBSD: define{{.*}} win64cc void @f7(ptr dead_on_unwind noalias writable sret(%struct.i128) align 8 %agg.result, ptr noundef %a) return a; } diff --git a/clang/test/CodeGen/paren-list-agg-init.cpp b/clang/test/CodeGen/paren-list-agg-init.cpp index 0e68beb5c3706..eb8d91a7f97f6 100644 --- a/clang/test/CodeGen/paren-list-agg-init.cpp +++ b/clang/test/CodeGen/paren-list-agg-init.cpp @@ -136,7 +136,7 @@ A foo1() { return a1; } -// CHECK: define dso_local void @{{.*foo2.*}}(ptr noalias sret([[STRUCT_B]]) align 8 [[AGG_RESULT:%.*]]) +// CHECK: define dso_local void @{{.*foo2.*}}(ptr dead_on_unwind noalias writable sret([[STRUCT_B]]) align 8 [[AGG_RESULT:%.*]]) // CHECK-NEXT: entry: // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[B1]], i64 24, i1 false) // CHECK-NEXT: ret void @@ -144,7 +144,7 @@ B foo2() { return b1; } -// CHECK: define dso_local void @{{.*foo3.*}}(ptr noalias sret([[STRUCT_C]]) align 8 [[AGG_RESULT:%.*]]) +// CHECK: define dso_local void @{{.*foo3.*}}(ptr dead_on_unwind noalias writable sret([[STRUCT_C]]) align 8 [[AGG_RESULT:%.*]]) // CHECK-NEXT: entry: // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[C1]], i64 48, i1 false) // CHECK-NEXT: ret void @@ -229,7 +229,7 @@ void foo7() { D d(A(1, 1), A(11, 11), A(111, 111)); } -// CHECK: dso_local void @{{.*foo8.*}}(ptr noalias sret([[STRUCT_D]]) align 8 [[AGG_RESULT:%.*]]) +// CHECK: dso_local void @{{.*foo8.*}}(ptr dead_on_unwind noalias writable sret([[STRUCT_D]]) align 8 [[AGG_RESULT:%.*]]) // CHECK-NEXT: entry: // CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[AGG_RESULT]], ptr align 8 [[D1]], i64 56, i1 false) // CHECK-NEXT: ret void diff --git a/clang/test/CodeGen/regcall2.c b/clang/test/CodeGen/regcall2.c index 96bc6615012af..c88d4e485b104 100644 --- a/clang/test/CodeGen/regcall2.c +++ b/clang/test/CodeGen/regcall2.c @@ -19,7 +19,7 @@ double __regcall bar(__sVector a) { } // FIXME: Do we need to change for Windows? -// Win: define dso_local x86_regcallcc void @__regcall3__foo(ptr noalias sret(%struct.__sVector) align 64 %agg.result, i32 noundef %a) #0 +// Win: define dso_local x86_regcallcc void @__regcall3__foo(ptr dead_on_unwind noalias writable sret(%struct.__sVector) align 64 %agg.result, i32 noundef %a) #0 // Win: define dso_local x86_regcallcc double @__regcall3__bar(ptr noundef %a) #0 // Win: attributes #0 = { noinline nounwind optnone "min-legal-vector-width"="0" "no-builtins" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+avx,+avx2,+avx512f,+avx512vl,+crc32,+cx8,+evex512,+f16c,+fma,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" } diff --git a/clang/test/CodeGen/regparm-struct.c b/clang/test/CodeGen/regparm-struct.c index 70901ca364d05..a533f6cedbba2 100644 --- a/clang/test/CodeGen/regparm-struct.c +++ b/clang/test/CodeGen/regparm-struct.c @@ -159,7 +159,7 @@ void g16(void) { } __attribute__((regparm(3))) struct s12 f17(int a, int b, int c); -// CHECK: declare void @f17(ptr inreg sret(%struct.s12) align 4, i32 inreg noundef, i32 inreg noundef, i32 noundef) +// CHECK: declare void @f17(ptr dead_on_unwind inreg writable sret(%struct.s12) align 4, i32 inreg noundef, i32 inreg noundef, i32 noundef) void g17(void) { f17(41, 42, 43); } diff --git a/clang/test/CodeGen/renderscript.c b/clang/test/CodeGen/renderscript.c index 8acf16566454c..1629665c1ffb8 100644 --- a/clang/test/CodeGen/renderscript.c +++ b/clang/test/CodeGen/renderscript.c @@ -83,15 +83,15 @@ void argLongInt(sLongInt s) {} // and coerced to [a x iNN] for 64-bit RenderScript // ============================================================================= -// CHECK-RS32: void @retShortCharShort(ptr noalias sret(%struct.sShortCharShort) align 2 %agg.result) +// CHECK-RS32: void @retShortCharShort(ptr dead_on_unwind noalias writable sret(%struct.sShortCharShort) align 2 %agg.result) // CHECK-RS64: [3 x i16] @retShortCharShort() sShortCharShort retShortCharShort(void) { sShortCharShort r; return r; } -// CHECK-RS32: void @retIntShortChar(ptr noalias sret(%struct.sIntShortChar) align 4 %agg.result) +// CHECK-RS32: void @retIntShortChar(ptr dead_on_unwind noalias writable sret(%struct.sIntShortChar) align 4 %agg.result) // CHECK-RS64: [2 x i32] @retIntShortChar() sIntShortChar retIntShortChar(void) { sIntShortChar r; return r; } -// CHECK-RS32: void @retLongInt(ptr noalias sret(%struct.sLongInt) align 8 %agg.result) +// CHECK-RS32: void @retLongInt(ptr dead_on_unwind noalias writable sret(%struct.sLongInt) align 8 %agg.result) // CHECK-RS64: [2 x i64] @retLongInt() sLongInt retLongInt(void) { sLongInt r; return r; } @@ -116,12 +116,12 @@ void argLong2Char(sLong2Char s) {} // 64-bit RenderScript // ============================================================================= -// CHECK-RS32: void @retInt5(ptr noalias sret(%struct.sInt5) align 4 %agg.result) -// CHECK-RS64: void @retInt5(ptr noalias sret(%struct.sInt5) align 4 %agg.result) +// CHECK-RS32: void @retInt5(ptr dead_on_unwind noalias writable sret(%struct.sInt5) align 4 %agg.result) +// CHECK-RS64: void @retInt5(ptr dead_on_unwind noalias writable sret(%struct.sInt5) align 4 %agg.result) sInt5 retInt5(void) { sInt5 r; return r;} -// CHECK-RS32: void @retLong2Char(ptr noalias sret(%struct.sLong2Char) align 8 %agg.result) -// CHECK-RS64: void @retLong2Char(ptr noalias sret(%struct.sLong2Char) align 8 %agg.result) +// CHECK-RS32: void @retLong2Char(ptr dead_on_unwind noalias writable sret(%struct.sLong2Char) align 8 %agg.result) +// CHECK-RS64: void @retLong2Char(ptr dead_on_unwind noalias writable sret(%struct.sLong2Char) align 8 %agg.result) sLong2Char retLong2Char(void) { sLong2Char r; return r;} // ============================================================================= @@ -135,6 +135,6 @@ typedef struct {long l1, l2, l3, l4, l5, l6, l7, l8, l9; } sLong9; // CHECK-RS64: void @argLong9(ptr noundef %s) void argLong9(sLong9 s) {} -// CHECK-RS32: void @retLong9(ptr noalias sret(%struct.sLong9) align 8 %agg.result) -// CHECK-RS64: void @retLong9(ptr noalias sret(%struct.sLong9) align 8 %agg.result) +// CHECK-RS32: void @retLong9(ptr dead_on_unwind noalias writable sret(%struct.sLong9) align 8 %agg.result) +// CHECK-RS64: void @retLong9(ptr dead_on_unwind noalias writable sret(%struct.sLong9) align 8 %agg.result) sLong9 retLong9(void) { sLong9 r; return r; } diff --git a/clang/test/CodeGen/sparcv9-abi.c b/clang/test/CodeGen/sparcv9-abi.c index 2d39c64c1c2ce..5e74a9a883cef 100644 --- a/clang/test/CodeGen/sparcv9-abi.c +++ b/clang/test/CodeGen/sparcv9-abi.c @@ -53,7 +53,7 @@ struct large { int x; }; -// CHECK-LABEL: define{{.*}} void @f_large(ptr noalias sret(%struct.large) align 8 %agg.result, ptr noundef %x) +// CHECK-LABEL: define{{.*}} void @f_large(ptr dead_on_unwind noalias writable sret(%struct.large) align 8 %agg.result, ptr noundef %x) struct large f_large(struct large x) { x.a += *x.b; x.b = 0; diff --git a/clang/test/CodeGen/sret.c b/clang/test/CodeGen/sret.c index 548581d3e3dc6..6d905e89b2c6f 100644 --- a/clang/test/CodeGen/sret.c +++ b/clang/test/CodeGen/sret.c @@ -9,15 +9,15 @@ struct abc { }; struct abc foo1(void); -// CHECK-DAG: declare {{.*}} @foo1(ptr sret(%struct.abc) +// CHECK-DAG: declare {{.*}} @foo1(ptr dead_on_unwind writable sret(%struct.abc) struct abc foo2(); -// CHECK-DAG: declare {{.*}} @foo2(ptr sret(%struct.abc) +// CHECK-DAG: declare {{.*}} @foo2(ptr dead_on_unwind writable sret(%struct.abc) struct abc foo3(void){} -// CHECK-DAG: define {{.*}} @foo3(ptr noalias sret(%struct.abc) +// CHECK-DAG: define {{.*}} @foo3(ptr dead_on_unwind noalias writable sret(%struct.abc) void bar(void) { struct abc dummy1 = foo1(); - // CHECK-DAG: call {{.*}} @foo1(ptr sret(%struct.abc) + // CHECK-DAG: call {{.*}} @foo1(ptr dead_on_unwind writable sret(%struct.abc) struct abc dummy2 = foo2(); - // CHECK-DAG: call {{.*}} @foo2(ptr sret(%struct.abc) + // CHECK-DAG: call {{.*}} @foo2(ptr dead_on_unwind writable sret(%struct.abc) } diff --git a/clang/test/CodeGen/vectorcall.c b/clang/test/CodeGen/vectorcall.c index b5f7efec67511..cb53ecc70351d 100644 --- a/clang/test/CodeGen/vectorcall.c +++ b/clang/test/CodeGen/vectorcall.c @@ -90,8 +90,8 @@ struct HVA4 __vectorcall hva6(struct HVA4 a, struct HVA4 b) { return b;} // X64: define dso_local x86_vectorcallcc %struct.HVA4 @"\01hva6@@128"(%struct.HVA4 inreg %a.coerce, ptr noundef %b) struct HVA5 __vectorcall hva7(void) {struct HVA5 a = {}; return a;} -// X86: define dso_local x86_vectorcallcc void @"\01hva7@@0"(ptr inreg noalias sret(%struct.HVA5) align 16 %agg.result) -// X64: define dso_local x86_vectorcallcc void @"\01hva7@@0"(ptr noalias sret(%struct.HVA5) align 16 %agg.result) +// X86: define dso_local x86_vectorcallcc void @"\01hva7@@0"(ptr dead_on_unwind inreg noalias writable sret(%struct.HVA5) align 16 %agg.result) +// X64: define dso_local x86_vectorcallcc void @"\01hva7@@0"(ptr dead_on_unwind noalias writable sret(%struct.HVA5) align 16 %agg.result) v4f32 __vectorcall hva8(v4f32 a, v4f32 b, v4f32 c, v4f32 d, int e, v4f32 f) {return f;} // X86: define dso_local x86_vectorcallcc <4 x float> @"\01hva8@@84"(<4 x float> inreg noundef %a, <4 x float> inreg noundef %b, <4 x float> inreg noundef %c, <4 x float> inreg noundef %d, i32 inreg noundef %e, <4 x float> inreg noundef %f) diff --git a/clang/test/CodeGen/windows-struct-abi.c b/clang/test/CodeGen/windows-struct-abi.c index 4431d91b63ca5..5e63c5b3344dd 100644 --- a/clang/test/CodeGen/windows-struct-abi.c +++ b/clang/test/CodeGen/windows-struct-abi.c @@ -34,7 +34,7 @@ struct f4 { struct f4 return_f4(void) { while (1); } -// CHECK: define dso_local void @return_f4(ptr noalias sret(%struct.f4) align 4 %agg.result) +// CHECK: define dso_local void @return_f4(ptr dead_on_unwind noalias writable sret(%struct.f4) align 4 %agg.result) void receive_f4(struct f4 a0) { } diff --git a/clang/test/CodeGen/windows-swiftcall.c b/clang/test/CodeGen/windows-swiftcall.c index 3e5c8a4d4b9d7..6c138a341835d 100644 --- a/clang/test/CodeGen/windows-swiftcall.c +++ b/clang/test/CodeGen/windows-swiftcall.c @@ -20,7 +20,7 @@ SWIFTCALL int indirect_result_2(OUT int *arg0, OUT float *arg1) { __builtin_unr typedef struct { char array[1024]; } struct_reallybig; SWIFTCALL struct_reallybig indirect_result_3(OUT int *arg0, OUT float *arg1) { __builtin_unreachable(); } -// CHECK-LABEL: define {{.*}} void @indirect_result_3(ptr noalias sret({{.*}}) {{.*}}, ptr noalias noundef align 4 dereferenceable(4){{.*}}, ptr noalias noundef align 4 dereferenceable(4){{.*}}) +// CHECK-LABEL: define {{.*}} void @indirect_result_3(ptr dead_on_unwind noalias writable sret({{.*}}) {{.*}}, ptr noalias noundef align 4 dereferenceable(4){{.*}}, ptr noalias noundef align 4 dereferenceable(4){{.*}}) SWIFTCALL void context_1(CONTEXT void *self) {} // CHECK-LABEL: define {{.*}} void @context_1(ptr noundef swiftself @@ -218,7 +218,7 @@ typedef struct { } struct_big_1; TEST(struct_big_1) -// CHECK-LABEL: define {{.*}} void @return_struct_big_1({{.*}} noalias sret +// CHECK-LABEL: define {{.*}} void @return_struct_big_1({{.*}} dead_on_unwind noalias writable sret // Should not be byval. // CHECK-LABEL: define {{.*}} void @take_struct_big_1(ptr noundef{{( %.*)?}}) diff --git a/clang/test/CodeGenCXX/aix-alignment.cpp b/clang/test/CodeGenCXX/aix-alignment.cpp index a8bb95814b1a4..d4397f3120ec5 100644 --- a/clang/test/CodeGenCXX/aix-alignment.cpp +++ b/clang/test/CodeGenCXX/aix-alignment.cpp @@ -29,7 +29,7 @@ typedef struct D { ~D(){}; } D; -// AIX: define void @_Z3foo1D(ptr noalias sret(%struct.D) align 4 %agg.result, ptr noundef %x) +// AIX: define void @_Z3foo1D(ptr dead_on_unwind noalias writable sret(%struct.D) align 4 %agg.result, ptr noundef %x) // AIX32 call void @llvm.memcpy.p0.p0.i32(ptr align 4 %agg.result, ptr align 4 %x, i32 16, i1 false) // AIX64: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %agg.result, ptr align 4 %x, i64 16, i1 false) D foo(D x) { return x; } diff --git a/clang/test/CodeGenCXX/arm-cc.cpp b/clang/test/CodeGenCXX/arm-cc.cpp index 967d10096f72b..68e1b7e4e1e46 100644 --- a/clang/test/CodeGenCXX/arm-cc.cpp +++ b/clang/test/CodeGenCXX/arm-cc.cpp @@ -16,5 +16,5 @@ void baz() { zed(a); } -// CHECK: declare void @_Z3fooPv(ptr sret(%class.SMLoc) align 4, ptr noundef) +// CHECK: declare void @_Z3fooPv(ptr dead_on_unwind writable sret(%class.SMLoc) align 4, ptr noundef) // CHECK: declare void @_Z3zed5SMLoc(ptr noundef) diff --git a/clang/test/CodeGenCXX/arm-swiftcall.cpp b/clang/test/CodeGenCXX/arm-swiftcall.cpp index 687e4c8b4dcbe..e60c1482700a4 100644 --- a/clang/test/CodeGenCXX/arm-swiftcall.cpp +++ b/clang/test/CodeGenCXX/arm-swiftcall.cpp @@ -105,7 +105,7 @@ struct struct_indirect_1 { }; TEST(struct_indirect_1) -// CHECK-LABEL: define {{.*}} void @return_struct_indirect_1({{.*}} noalias sret +// CHECK-LABEL: define {{.*}} void @return_struct_indirect_1({{.*}} dead_on_unwind noalias writable sret // Should not be byval. // CHECK-LABEL: define {{.*}} void @take_struct_indirect_1(ptr noundef{{( %.*)?}}) diff --git a/clang/test/CodeGenCXX/attr-musttail.cpp b/clang/test/CodeGenCXX/attr-musttail.cpp index b8a1961d5eb77..720e50c5a240f 100644 --- a/clang/test/CodeGenCXX/attr-musttail.cpp +++ b/clang/test/CodeGenCXX/attr-musttail.cpp @@ -162,7 +162,7 @@ HasNonTrivialCopyConstructor TestNonElidableCopyConstructor() { [[clang::musttail]] return (((ReturnsClassByValue()))); } -// CHECK: musttail call void @_Z19ReturnsClassByValuev(ptr sret(%struct.HasNonTrivialCopyConstructor) align 1 %agg.result) +// CHECK: musttail call void @_Z19ReturnsClassByValuev(ptr dead_on_unwind writable sret(%struct.HasNonTrivialCopyConstructor) align 1 %agg.result) struct HasNonTrivialCopyConstructor2 { // Copy constructor works even if it has extra default params. @@ -191,8 +191,8 @@ LargeWithCopyConstructor TestLargeWithCopyConstructor() { [[clang::musttail]] return ReturnsLarge(); } -// CHECK: define dso_local void @_Z28TestLargeWithCopyConstructorv(ptr noalias sret(%struct.LargeWithCopyConstructor) align 1 %agg.result) -// CHECK: musttail call void @_Z12ReturnsLargev(ptr sret(%struct.LargeWithCopyConstructor) align 1 %agg.result) +// CHECK: define dso_local void @_Z28TestLargeWithCopyConstructorv(ptr dead_on_unwind noalias writable sret(%struct.LargeWithCopyConstructor) align 1 %agg.result) +// CHECK: musttail call void @_Z12ReturnsLargev(ptr dead_on_unwind writable sret(%struct.LargeWithCopyConstructor) align 1 %agg.result) using IntFunctionType = int(); IntFunctionType *ReturnsIntFunction(); diff --git a/clang/test/CodeGenCXX/call-with-static-chain.cpp b/clang/test/CodeGenCXX/call-with-static-chain.cpp index 06c3f15396a86..61011a65e4a2c 100644 --- a/clang/test/CodeGenCXX/call-with-static-chain.cpp +++ b/clang/test/CodeGenCXX/call-with-static-chain.cpp @@ -25,8 +25,8 @@ void test() { // CHECK64: call i32 @f1(ptr nest noundef @f1 __builtin_call_with_static_chain(f1(a, a, a, a), f1); - // CHECK32: call void @f2(ptr sret(%struct.B) align 4 %{{[0-9a-z]+}}, ptr nest noundef @f2) - // CHECK64: call void @f2(ptr sret(%struct.B) align 8 %{{[0-9a-z]+}}, ptr nest noundef @f2) + // CHECK32: call void @f2(ptr dead_on_unwind writable sret(%struct.B) align 4 %{{[0-9a-z]+}}, ptr nest noundef @f2) + // CHECK64: call void @f2(ptr dead_on_unwind writable sret(%struct.B) align 8 %{{[0-9a-z]+}}, ptr nest noundef @f2) __builtin_call_with_static_chain(f2(), f2); // CHECK32: call i64 @f3(ptr nest noundef @f3) diff --git a/clang/test/CodeGenCXX/conditional-gnu-ext.cpp b/clang/test/CodeGenCXX/conditional-gnu-ext.cpp index b17e0f7bb9a22..3d3d210f22f69 100644 --- a/clang/test/CodeGenCXX/conditional-gnu-ext.cpp +++ b/clang/test/CodeGenCXX/conditional-gnu-ext.cpp @@ -94,7 +94,7 @@ namespace test3 { B test1() { // CHECK-LABEL: define{{.*}} void @_ZN5test35test1Ev( // CHECK: [[TEMP:%.*]] = alloca [[B:%.*]], - // CHECK: call void @_ZN5test312test1_helperEv(ptr sret([[B]]) align 1 [[TEMP]]) + // CHECK: call void @_ZN5test312test1_helperEv(ptr dead_on_unwind writable sret([[B]]) align 1 [[TEMP]]) // CHECK-NEXT: [[BOOL:%.*]] = call noundef zeroext i1 @_ZN5test31BcvbEv(ptr {{[^,]*}} [[TEMP]]) // CHECK-NEXT: br i1 [[BOOL]] // CHECK: call void @_ZN5test31BC1ERKS0_(ptr {{[^,]*}} [[RESULT:%.*]], ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[TEMP]]) @@ -117,7 +117,7 @@ namespace test3 { // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] // CHECK-NEXT: [[BOOL:%.*]] = call noundef zeroext i1 @_ZN5test31BcvbEv(ptr {{[^,]*}} [[T0]]) // CHECK-NEXT: br i1 [[BOOL]] - // CHECK: call void @_ZN5test31BcvNS_1AEEv(ptr sret([[A:%.*]]) align 1 [[RESULT:%.*]], ptr {{[^,]*}} [[T0]]) + // CHECK: call void @_ZN5test31BcvNS_1AEEv(ptr dead_on_unwind writable sret([[A:%.*]]) align 1 [[RESULT:%.*]], ptr {{[^,]*}} [[T0]]) // CHECK-NEXT: br label // CHECK: call void @_ZN5test31AC1Ev(ptr {{[^,]*}} [[RESULT]]) // CHECK-NEXT: br label @@ -128,10 +128,10 @@ namespace test3 { A test3() { // CHECK-LABEL: define{{.*}} void @_ZN5test35test3Ev( // CHECK: [[TEMP:%.*]] = alloca [[B]], - // CHECK: call void @_ZN5test312test3_helperEv(ptr sret([[B]]) align 1 [[TEMP]]) + // CHECK: call void @_ZN5test312test3_helperEv(ptr dead_on_unwind writable sret([[B]]) align 1 [[TEMP]]) // CHECK-NEXT: [[BOOL:%.*]] = call noundef zeroext i1 @_ZN5test31BcvbEv(ptr {{[^,]*}} [[TEMP]]) // CHECK-NEXT: br i1 [[BOOL]] - // CHECK: call void @_ZN5test31BcvNS_1AEEv(ptr sret([[A]]) align 1 [[RESULT:%.*]], ptr {{[^,]*}} [[TEMP]]) + // CHECK: call void @_ZN5test31BcvNS_1AEEv(ptr dead_on_unwind writable sret([[A]]) align 1 [[RESULT:%.*]], ptr {{[^,]*}} [[TEMP]]) // CHECK-NEXT: br label // CHECK: call void @_ZN5test31AC1Ev(ptr {{[^,]*}} [[RESULT]]) // CHECK-NEXT: br label diff --git a/clang/test/CodeGenCXX/cxx1z-copy-omission.cpp b/clang/test/CodeGenCXX/cxx1z-copy-omission.cpp index db6671bcd301b..e64d163fd3d6c 100644 --- a/clang/test/CodeGenCXX/cxx1z-copy-omission.cpp +++ b/clang/test/CodeGenCXX/cxx1z-copy-omission.cpp @@ -19,7 +19,7 @@ void g() { // CHECK: %[[A:.*]] = alloca // CHECK-NOT: alloca // CHECK-NOT: call - // CHECK: call {{.*}} @_Z1fv(ptr sret({{.*}}) align 4 %[[A]]) + // CHECK: call {{.*}} @_Z1fv(ptr dead_on_unwind writable sret({{.*}}) align 4 %[[A]]) A a = A( A{ f() } ); // CHECK-NOT: call @@ -40,7 +40,7 @@ void h() { // CHECK-NOT: alloca // CHECK-NOT: call - // CHECK: call {{.*}} @_Z1fv(ptr sret({{.*}}) align 4 %[[A]]) + // CHECK: call {{.*}} @_Z1fv(ptr dead_on_unwind writable sret({{.*}}) align 4 %[[A]]) // CHECK-NOT: call // CHECK: call {{.*}} @_Z1f1A(ptr noundef %[[A]]) f(f()); diff --git a/clang/test/CodeGenCXX/cxx1z-lambda-star-this.cpp b/clang/test/CodeGenCXX/cxx1z-lambda-star-this.cpp index 63bfe5603b694..1388f1b87889a 100644 --- a/clang/test/CodeGenCXX/cxx1z-lambda-star-this.cpp +++ b/clang/test/CodeGenCXX/cxx1z-lambda-star-this.cpp @@ -10,7 +10,7 @@ namespace ns1 { int X = A{}.foo()(); } //end ns1 -//CHECK: @"?foo@A@@QAE?A?@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%class.anon) align 8 %[[A_LAMBDA_RETVAL:.*]]) +//CHECK: @"?foo@A@@QAE?A?@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%class.anon) align 8 %[[A_LAMBDA_RETVAL:.*]]) // get the first object with the closure type, which is of type 'struct.A' //CHECK: %[[I0:.+]] = getelementptr inbounds %[[A_LAMBDA]], ptr %[[A_LAMBDA_RETVAL]], i32 0, i32 0 // copy the contents ... @@ -24,6 +24,6 @@ struct B { namespace ns2 { int X = B{}.bar()(); } -//CHECK: @"?bar@B@@QAE?A?@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%class.anon.0) align 4 %agg.result) +//CHECK: @"?bar@B@@QAE?A?@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%class.anon.0) align 4 %agg.result) //CHECK: %[[I20:.+]] = getelementptr inbounds %class.anon.0, ptr %agg.result, i32 0, i32 0 //CHECK: store ptr %this1, ptr %[[I20]], align 4 diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp index 483876cc212e3..e8179f9828fb6 100644 --- a/clang/test/CodeGenCXX/exceptions.cpp +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -142,12 +142,12 @@ namespace test1 { // CHECK: [[ACTIVE:%.*]] = alloca i1 // CHECK: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8) // CHECK-NEXT: store i1 true, ptr [[ACTIVE]] - // CHECK-NEXT: invoke void @_ZN5test15makeBEv(ptr sret([[B:%.*]]) align 4 [[T0:%.*]]) + // CHECK-NEXT: invoke void @_ZN5test15makeBEv(ptr dead_on_unwind writable sret([[B:%.*]]) align 4 [[T0:%.*]]) // CHECK: [[T1:%.*]] = invoke i32 @_ZN5test11BcviEv(ptr {{[^,]*}} [[T0]]) // CHECK: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[T1]]) // CHECK: store i1 false, ptr [[ACTIVE]] // CHECK-NEXT: store ptr [[NEW]], ptr [[X]], align 8 - // CHECK: invoke void @_ZN5test15makeBEv(ptr sret([[B:%.*]]) align 4 [[T2:%.*]]) + // CHECK: invoke void @_ZN5test15makeBEv(ptr dead_on_unwind writable sret([[B:%.*]]) align 4 [[T2:%.*]]) // CHECK: [[RET:%.*]] = load ptr, ptr [[X]], align 8 // CHECK98: invoke void @_ZN5test11BD1Ev(ptr {{[^,]*}} [[T2]]) @@ -231,7 +231,7 @@ namespace test3 { // CHECK-NEXT: store ptr [[NEW]], ptr [[SAVED0]] // CHECK-NEXT: store ptr [[FOO]], ptr [[SAVED1]] // CHECK-NEXT: store i1 true, ptr [[CLEANUPACTIVE]] - // CHECK-NEXT: invoke void @_ZN5test35makeAEv(ptr sret([[A:%.*]]) align 8 [[NEW]]) + // CHECK-NEXT: invoke void @_ZN5test35makeAEv(ptr dead_on_unwind writable sret([[A:%.*]]) align 8 [[NEW]]) // CHECK: br label // -> cond.end new(foo(),10.0) A(makeA()) : diff --git a/clang/test/CodeGenCXX/homogeneous-aggregates.cpp b/clang/test/CodeGenCXX/homogeneous-aggregates.cpp index bd83b9f932aad..63ffc6b5bfac8 100644 --- a/clang/test/CodeGenCXX/homogeneous-aggregates.cpp +++ b/clang/test/CodeGenCXX/homogeneous-aggregates.cpp @@ -39,10 +39,10 @@ struct I2 : Base2 {}; struct I3 : Base2 {}; struct D5 : I1, I2, I3 {}; // homogeneous aggregate -// PPC: define{{.*}} void @_Z7func_D12D1(ptr noalias sret(%struct.D1) align 8 %agg.result, [3 x i64] %x.coerce) -// ARM32: define{{.*}} arm_aapcs_vfpcc void @_Z7func_D12D1(ptr noalias sret(%struct.D1) align 8 %agg.result, [3 x i64] %x.coerce) -// ARM64: define{{.*}} void @_Z7func_D12D1(ptr noalias sret(%struct.D1) align 8 %agg.result, ptr noundef %x) -// X64: define dso_local x86_vectorcallcc void @"\01_Z7func_D12D1@@24"(ptr noalias sret(%struct.D1) align 8 %agg.result, ptr noundef %x) +// PPC: define{{.*}} void @_Z7func_D12D1(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, [3 x i64] %x.coerce) +// ARM32: define{{.*}} arm_aapcs_vfpcc void @_Z7func_D12D1(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, [3 x i64] %x.coerce) +// ARM64: define{{.*}} void @_Z7func_D12D1(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, ptr noundef %x) +// X64: define dso_local x86_vectorcallcc void @"\01_Z7func_D12D1@@24"(ptr dead_on_unwind noalias writable sret(%struct.D1) align 8 %agg.result, ptr noundef %x) D1 CC func_D1(D1 x) { return x; } // PPC: define{{.*}} [3 x double] @_Z7func_D22D2([3 x double] %x.coerce) @@ -51,9 +51,9 @@ D1 CC func_D1(D1 x) { return x; } // X64: define dso_local x86_vectorcallcc %struct.D2 @"\01_Z7func_D22D2@@24"(%struct.D2 inreg %x.coerce) D2 CC func_D2(D2 x) { return x; } -// PPC: define{{.*}} void @_Z7func_D32D3(ptr noalias sret(%struct.D3) align 8 %agg.result, [4 x i64] %x.coerce) -// ARM32: define{{.*}} arm_aapcs_vfpcc void @_Z7func_D32D3(ptr noalias sret(%struct.D3) align 8 %agg.result, [4 x i64] %x.coerce) -// ARM64: define{{.*}} void @_Z7func_D32D3(ptr noalias sret(%struct.D3) align 8 %agg.result, ptr noundef %x) +// PPC: define{{.*}} void @_Z7func_D32D3(ptr dead_on_unwind noalias writable sret(%struct.D3) align 8 %agg.result, [4 x i64] %x.coerce) +// ARM32: define{{.*}} arm_aapcs_vfpcc void @_Z7func_D32D3(ptr dead_on_unwind noalias writable sret(%struct.D3) align 8 %agg.result, [4 x i64] %x.coerce) +// ARM64: define{{.*}} void @_Z7func_D32D3(ptr dead_on_unwind noalias writable sret(%struct.D3) align 8 %agg.result, ptr noundef %x) D3 CC func_D3(D3 x) { return x; } // PPC: define{{.*}} [4 x double] @_Z7func_D42D4([4 x double] %x.coerce) @@ -133,13 +133,13 @@ struct HasEmptyBase : public Empty { struct HasPodBase : public Pod {}; // WOA64-LABEL: define dso_local %"struct.pr47611::Pod" @"?copy@pr47611@@YA?AUPod@1@PEAU21@@Z"(ptr noundef %x) Pod copy(Pod *x) { return *x; } // MSVC: ldp d0,d1,[x0], Clang: ldp d0,d1,[x0] -// WOA64-LABEL: define dso_local void @"?copy@pr47611@@YA?AUNotCXX14Aggregate@1@PEAU21@@Z"(ptr inreg noalias sret(%"struct.pr47611::NotCXX14Aggregate") align 8 %agg.result, ptr noundef %x) +// WOA64-LABEL: define dso_local void @"?copy@pr47611@@YA?AUNotCXX14Aggregate@1@PEAU21@@Z"(ptr dead_on_unwind inreg noalias writable sret(%"struct.pr47611::NotCXX14Aggregate") align 8 %agg.result, ptr noundef %x) NotCXX14Aggregate copy(NotCXX14Aggregate *x) { return *x; } // MSVC: stp x8,x9,[x0], Clang: str q0,[x0] // WOA64-LABEL: define dso_local [2 x i64] @"?copy@pr47611@@YA?AUNotPod@1@PEAU21@@Z"(ptr noundef %x) NotPod copy(NotPod *x) { return *x; } -// WOA64-LABEL: define dso_local void @"?copy@pr47611@@YA?AUHasEmptyBase@1@PEAU21@@Z"(ptr inreg noalias sret(%"struct.pr47611::HasEmptyBase") align 8 %agg.result, ptr noundef %x) +// WOA64-LABEL: define dso_local void @"?copy@pr47611@@YA?AUHasEmptyBase@1@PEAU21@@Z"(ptr dead_on_unwind inreg noalias writable sret(%"struct.pr47611::HasEmptyBase") align 8 %agg.result, ptr noundef %x) HasEmptyBase copy(HasEmptyBase *x) { return *x; } -// WOA64-LABEL: define dso_local void @"?copy@pr47611@@YA?AUHasPodBase@1@PEAU21@@Z"(ptr inreg noalias sret(%"struct.pr47611::HasPodBase") align 8 %agg.result, ptr noundef %x) +// WOA64-LABEL: define dso_local void @"?copy@pr47611@@YA?AUHasPodBase@1@PEAU21@@Z"(ptr dead_on_unwind inreg noalias writable sret(%"struct.pr47611::HasPodBase") align 8 %agg.result, ptr noundef %x) HasPodBase copy(HasPodBase *x) { return *x; } void call_copy_pod(Pod *pod) { @@ -151,7 +151,7 @@ void call_copy_pod(Pod *pod) { void call_copy_notcxx14aggregate(NotCXX14Aggregate *notcxx14aggregate) { *notcxx14aggregate = copy(notcxx14aggregate); // WOA64-LABEL: define dso_local void @"?call_copy_notcxx14aggregate@pr47611@@YAXPEAUNotCXX14Aggregate@1@@Z" - // WOA64: call void @"?copy@pr47611@@YA?AUNotCXX14Aggregate@1@PEAU21@@Z"(ptr inreg sret(%"struct.pr47611::NotCXX14Aggregate") align 8 %{{.*}}, ptr noundef %{{.*}}) + // WOA64: call void @"?copy@pr47611@@YA?AUNotCXX14Aggregate@1@PEAU21@@Z"(ptr dead_on_unwind inreg writable sret(%"struct.pr47611::NotCXX14Aggregate") align 8 %{{.*}}, ptr noundef %{{.*}}) } void call_copy_notpod(NotPod *notPod) { @@ -163,13 +163,13 @@ void call_copy_notpod(NotPod *notPod) { void call_copy_hasemptybase(HasEmptyBase *hasEmptyBase) { *hasEmptyBase = copy(hasEmptyBase); // WOA64-LABEL: define dso_local void @"?call_copy_hasemptybase@pr47611@@YAXPEAUHasEmptyBase@1@@Z" - // WOA64: call void @"?copy@pr47611@@YA?AUHasEmptyBase@1@PEAU21@@Z"(ptr inreg sret(%"struct.pr47611::HasEmptyBase") align 8 %{{.*}}, ptr noundef %{{.*}}) + // WOA64: call void @"?copy@pr47611@@YA?AUHasEmptyBase@1@PEAU21@@Z"(ptr dead_on_unwind inreg writable sret(%"struct.pr47611::HasEmptyBase") align 8 %{{.*}}, ptr noundef %{{.*}}) } void call_copy_haspodbase(HasPodBase *hasPodBase) { *hasPodBase = copy(hasPodBase); // WOA64-LABEL: define dso_local void @"?call_copy_haspodbase@pr47611@@YAXPEAUHasPodBase@1@@Z" - // WOA64: call void @"?copy@pr47611@@YA?AUHasPodBase@1@PEAU21@@Z"(ptr inreg sret(%"struct.pr47611::HasPodBase") align 8 %{{.*}}, ptr noundef %{{.*}}) + // WOA64: call void @"?copy@pr47611@@YA?AUHasPodBase@1@PEAU21@@Z"(ptr dead_on_unwind inreg writable sret(%"struct.pr47611::HasPodBase") align 8 %{{.*}}, ptr noundef %{{.*}}) } } // namespace pr47611 @@ -300,5 +300,5 @@ test f(test *x) { return *x; } struct base2 { double v; }; struct test2 : base2 { test2(double); protected: double v2;}; test2 f(test2 *x) { return *x; } -// WOA64: define dso_local void @"?f@pr62223@@YA?AUtest2@1@PEAU21@@Z"(ptr inreg noalias sret(%"struct.pr62223::test2") align 8 %{{.*}}, ptr noundef %{{.*}}) +// WOA64: define dso_local void @"?f@pr62223@@YA?AUtest2@1@PEAU21@@Z"(ptr dead_on_unwind inreg noalias writable sret(%"struct.pr62223::test2") align 8 %{{.*}}, ptr noundef %{{.*}}) } diff --git a/clang/test/CodeGenCXX/lambda-expressions.cpp b/clang/test/CodeGenCXX/lambda-expressions.cpp index 3ad982a195cc9..b929aa0c67513 100644 --- a/clang/test/CodeGenCXX/lambda-expressions.cpp +++ b/clang/test/CodeGenCXX/lambda-expressions.cpp @@ -193,8 +193,8 @@ namespace pr28595 { // CHECK-NEXT: call noundef i32 @"_ZZ1fvENK3$_0clEii" // CHECK-NEXT: ret i32 -// CHECK-LABEL: define internal void @"_ZZ1hvEN3$_08__invokeEv"(ptr noalias sret(%struct.A) align 1 %agg.result) {{.*}} { -// CHECK: call void @"_ZZ1hvENK3$_0clEv"(ptr sret(%struct.A) align 1 %agg.result, +// CHECK-LABEL: define internal void @"_ZZ1hvEN3$_08__invokeEv"(ptr dead_on_unwind noalias writable sret(%struct.A) align 1 %agg.result) {{.*}} { +// CHECK: call void @"_ZZ1hvENK3$_0clEv"(ptr dead_on_unwind writable sret(%struct.A) align 1 %agg.result, // CHECK-NEXT: ret void struct A { ~A(); }; void h() { diff --git a/clang/test/CodeGenCXX/matrix-casts.cpp b/clang/test/CodeGenCXX/matrix-casts.cpp index 4369d99a34915..0a946e464adef 100644 --- a/clang/test/CodeGenCXX/matrix-casts.cpp +++ b/clang/test/CodeGenCXX/matrix-casts.cpp @@ -324,7 +324,7 @@ class Foo { }; Foo class_constructor_matrix_ty(matrix_5_5 m) { - // CHECK-LABEL: define void @_Z27class_constructor_matrix_tyu11matrix_typeILm5ELm5EiE(ptr noalias sret(%class.Foo) align 4 %agg.result, <25 x i32> noundef %m) + // CHECK-LABEL: define void @_Z27class_constructor_matrix_tyu11matrix_typeILm5ELm5EiE(ptr dead_on_unwind noalias writable sret(%class.Foo) align 4 %agg.result, <25 x i32> noundef %m) // CHECK: [[M:%.*]] = load <25 x i32>, ptr {{.*}}, align 4 // CHECK-NEXT: call void @_ZN3FooC1Eu11matrix_typeILm5ELm5EiE(ptr noundef nonnull align 4 dereferenceable(40) %agg.result, <25 x i32> noundef [[M]]) // CHECK-NEXT: ret void @@ -338,7 +338,7 @@ struct Bar { }; Bar struct_constructor_matrix_ty(matrix_4_4 m) { - // CHECK-LABEL: define void @_Z28struct_constructor_matrix_tyu11matrix_typeILm4ELm4EfE(ptr noalias sret(%struct.Bar) align 4 %agg.result, <16 x float> noundef %m) + // CHECK-LABEL: define void @_Z28struct_constructor_matrix_tyu11matrix_typeILm4ELm4EfE(ptr dead_on_unwind noalias writable sret(%struct.Bar) align 4 %agg.result, <16 x float> noundef %m) // CHECK: [[M:%.*]] = load <16 x float>, ptr {{.*}}, align 4 // CHECK-NEXT: call void @_ZN3BarC1Eu11matrix_typeILm4ELm4EfE(ptr noundef nonnull align 4 dereferenceable(40) %agg.result, <16 x float> noundef [[M]]) // CHECK-NEXT: ret void diff --git a/clang/test/CodeGenCXX/matrix-type-builtins.cpp b/clang/test/CodeGenCXX/matrix-type-builtins.cpp index 732fe1a18db3b..9c334a6858f15 100644 --- a/clang/test/CodeGenCXX/matrix-type-builtins.cpp +++ b/clang/test/CodeGenCXX/matrix-type-builtins.cpp @@ -19,7 +19,7 @@ MyMatrix transpose(const MyMatrix &M) { void test_transpose_template1() { // CHECK-LABEL: define{{.*}} void @_Z24test_transpose_template1v() - // CHECK: call void @_Z9transposeIiLj4ELj10EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.0) align 4 %M1_t, ptr noundef nonnull align 4 dereferenceable(160) %M1) + // CHECK: call void @_Z9transposeIiLj4ELj10EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr dead_on_unwind writable sret(%struct.MyMatrix.0) align 4 %M1_t, ptr noundef nonnull align 4 dereferenceable(160) %M1) // CHECK-LABEL: define linkonce_odr void @_Z9transposeIiLj4ELj10EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE( // CHECK: [[M:%.*]] = load <40 x i32>, ptr {{.*}}, align 4 @@ -31,9 +31,9 @@ void test_transpose_template1() { void test_transpose_template2(MyMatrix &M) { // CHECK-LABEL: define{{.*}} void @_Z24test_transpose_template2R8MyMatrixIdLj7ELj6EE( - // CHECK: call void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.1) align 8 %ref.tmp1, ptr noundef nonnull align 8 dereferenceable(336) %0) - // CHECK-NEXT: call void @_Z9transposeIdLj6ELj7EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.2) align 8 %ref.tmp, ptr noundef nonnull align 8 dereferenceable(336) %ref.tmp1) - // CHECK-NEXT: call void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.1) align 8 %M2_t, ptr noundef nonnull align 8 dereferenceable(336) %ref.tmp) + // CHECK: call void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr dead_on_unwind writable sret(%struct.MyMatrix.1) align 8 %ref.tmp1, ptr noundef nonnull align 8 dereferenceable(336) %0) + // CHECK-NEXT: call void @_Z9transposeIdLj6ELj7EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr dead_on_unwind writable sret(%struct.MyMatrix.2) align 8 %ref.tmp, ptr noundef nonnull align 8 dereferenceable(336) %ref.tmp1) + // CHECK-NEXT: call void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr dead_on_unwind writable sret(%struct.MyMatrix.1) align 8 %M2_t, ptr noundef nonnull align 8 dereferenceable(336) %ref.tmp) // CHECK-LABEL: define linkonce_odr void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE( // CHECK: [[M:%.*]] = load <42 x double>, ptr {{.*}}, align 8 diff --git a/clang/test/CodeGenCXX/matrix-type.cpp b/clang/test/CodeGenCXX/matrix-type.cpp index 79bceabb115f8..d93db29d4d0aa 100644 --- a/clang/test/CodeGenCXX/matrix-type.cpp +++ b/clang/test/CodeGenCXX/matrix-type.cpp @@ -127,7 +127,7 @@ void matrix_template_reference(MatrixClassTemplate &a, MatrixCla } MatrixClassTemplate matrix_template_reference_caller(float *Data) { - // CHECK-LABEL: define{{.*}} void @_Z32matrix_template_reference_callerPf(ptr noalias sret(%class.MatrixClassTemplate) align 8 %agg.result, ptr %Data + // CHECK-LABEL: define{{.*}} void @_Z32matrix_template_reference_callerPf(ptr dead_on_unwind noalias writable sret(%class.MatrixClassTemplate) align 8 %agg.result, ptr %Data // CHECK-NEXT: entry: // CHECK-NEXT: %Data.addr = alloca ptr, align 8 // CHECK-NEXT: %Arg = alloca %class.MatrixClassTemplate, align 8 diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp index fde27c6ce85db..668a27e9d2623 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-byval-sret.cpp @@ -49,7 +49,7 @@ A B::qux(A x) { } // CHECK-LABEL: define dso_local x86_fastcallcc void @"?qux@B@@QAI?AUA@@U2@@Z" -// CHECK: (ptr inreg noundef %this, ptr inreg noalias sret(%struct.A) align 4 %agg.result, ptr inalloca(<{ %struct.A }>) %0) +// CHECK: (ptr inreg noundef %this, ptr dead_on_unwind inreg noalias writable sret(%struct.A) align 4 %agg.result, ptr inalloca(<{ %struct.A }>) %0) // CHECK: ret void int main() { @@ -67,4 +67,4 @@ int main() { // CHECK: call x86_stdcallcc ptr @"?baz@B@@QAG?AUA@@U2@@Z" // CHECK: (ptr inalloca(<{ ptr, ptr, %struct.A }>) %{{[^,]*}}) // CHECK: call x86_fastcallcc void @"?qux@B@@QAI?AUA@@U2@@Z" -// CHECK: (ptr inreg noundef %{{[^,]*}}, ptr inreg sret(%struct.A) align 4 %{{.*}}, ptr inalloca(<{ %struct.A }>) %{{[^,]*}}) +// CHECK: (ptr inreg noundef %{{[^,]*}}, ptr dead_on_unwind inreg writable sret(%struct.A) align 4 %{{.*}}, ptr inalloca(<{ %struct.A }>) %{{[^,]*}}) diff --git a/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp b/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp index 66ecf500a8693..4c485fc3142ab 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp @@ -86,10 +86,10 @@ C::C() {} // force emission // CHECK32-NEXT: ret ptr %[[rv]] // CHECK64-LABEL: define linkonce_odr dso_local void @"?foo@C@sret_thunk@@W7EAA?AUAgg@2@U32@@Z" -// CHECK64: (ptr noundef %this, ptr noalias sret(%"struct.sret_thunk::Agg") align 4 %agg.result, ptr noundef %x) +// CHECK64: (ptr noundef %this, ptr dead_on_unwind noalias writable sret(%"struct.sret_thunk::Agg") align 4 %agg.result, ptr noundef %x) // CHECK64: getelementptr i8, ptr %{{.*}}, i32 -8 // CHECK64: call void @"?foo@C@sret_thunk@@UEAA?AUAgg@2@U32@@Z" -// CHECK64: (ptr {{[^,]*}} %{{.*}}, ptr sret(%"struct.sret_thunk::Agg") align 4 %agg.result, ptr noundef %x) +// CHECK64: (ptr {{[^,]*}} %{{.*}}, ptr dead_on_unwind writable sret(%"struct.sret_thunk::Agg") align 4 %agg.result, ptr noundef %x) // CHECK64-NOT: call // CHECK64: ret void } diff --git a/clang/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp b/clang/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp index b4a6ff8e6d0ff..a1faab25b109c 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp @@ -19,9 +19,9 @@ S C::variadic_sret(const char *f, ...) { return S(); } S C::cdecl_sret() { return S(); } S C::byval_and_sret(S a) { return S(); } -// CHECK: define dso_local void @"?variadic_sret@C@@QAA?AUS@@PBDZZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.S) align 4 %agg.result, ptr noundef %f, ...) -// CHECK: define dso_local void @"?cdecl_sret@C@@QAA?AUS@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.S) align 4 %agg.result) -// CHECK: define dso_local void @"?byval_and_sret@C@@QAA?AUS@@U2@@Z"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.S) align 4 %agg.result, ptr noundef byval(%struct.S) align 4 %a) +// CHECK: define dso_local void @"?variadic_sret@C@@QAA?AUS@@PBDZZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.S) align 4 %agg.result, ptr noundef %f, ...) +// CHECK: define dso_local void @"?cdecl_sret@C@@QAA?AUS@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.S) align 4 %agg.result) +// CHECK: define dso_local void @"?byval_and_sret@C@@QAA?AUS@@U2@@Z"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.S) align 4 %agg.result, ptr noundef byval(%struct.S) align 4 %a) int main() { C c; @@ -41,4 +41,4 @@ struct A { S A::f(int x) { return S(); } -// CHECK-LABEL: define dso_local x86_fastcallcc void @"?f@A@@QAI?AUS@@H@Z"(ptr inreg noundef nonnull align 1 dereferenceable(1) %this, ptr inreg noalias sret(%struct.S) align 4 %agg.result, i32 noundef %x) +// CHECK-LABEL: define dso_local x86_fastcallcc void @"?f@A@@QAI?AUS@@H@Z"(ptr inreg noundef nonnull align 1 dereferenceable(1) %this, ptr dead_on_unwind inreg noalias writable sret(%struct.S) align 4 %agg.result, i32 noundef %x) diff --git a/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp index 4bff7ccf8986b..f00cf90762756 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp @@ -18,9 +18,9 @@ void HasEHCleanup() { // WIN32-LABEL: define dso_local void @"?HasEHCleanup@@YAXXZ"() {{.*}} { // WIN32: %[[base:.*]] = call ptr @llvm.stacksave.p0() // If this call throws, we have to restore the stack. -// WIN32: call void @"?getA@@YA?AUA@@XZ"(ptr sret(%struct.A) align 4 %{{.*}}) +// WIN32: call void @"?getA@@YA?AUA@@XZ"(ptr dead_on_unwind writable sret(%struct.A) align 4 %{{.*}}) // If this call throws, we have to cleanup the first temporary. -// WIN32: invoke void @"?getA@@YA?AUA@@XZ"(ptr sret(%struct.A) align 4 %{{.*}}) +// WIN32: invoke void @"?getA@@YA?AUA@@XZ"(ptr dead_on_unwind writable sret(%struct.A) align 4 %{{.*}}) // If this call throws, we have to cleanup the stacksave. // WIN32: call noundef i32 @"?TakesTwo@@YAHUA@@0@Z" // WIN32: call void @llvm.stackrestore @@ -42,8 +42,8 @@ void HasEHCleanupNoexcept() noexcept { // With exceptions, we need to clean up at least one of these temporaries. // WIN32-LABEL: define dso_local void @"?HasEHCleanupNoexcept@@YAXXZ"() {{.*}} { // WIN32: %[[base:.*]] = call ptr @llvm.stacksave.p0() -// WIN32: invoke void @"?getA@@YA?AUA@@XZ"(ptr sret(%struct.A) align 4 %{{.*}}) -// WIN32: invoke void @"?getA@@YA?AUA@@XZ"(ptr sret(%struct.A) align 4 %{{.*}}) +// WIN32: invoke void @"?getA@@YA?AUA@@XZ"(ptr dead_on_unwind writable sret(%struct.A) align 4 %{{.*}}) +// WIN32: invoke void @"?getA@@YA?AUA@@XZ"(ptr dead_on_unwind writable sret(%struct.A) align 4 %{{.*}}) // WIN32: invoke noundef i32 @"?TakesTwo@@YAHUA@@0@Z" // WIN32: call void @llvm.stackrestore // WIN32: ret void diff --git a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp index 9d737e3979ddd..585167d0a1423 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp @@ -87,58 +87,58 @@ void call_bools_and_chars() { // Returning structs that fit into a register. Small small_return() { return Small(); } -// LINUX-LABEL: define{{.*}} void @_Z12small_returnv(ptr noalias sret(%struct.Small) align 4 %agg.result) +// LINUX-LABEL: define{{.*}} void @_Z12small_returnv(ptr dead_on_unwind noalias writable sret(%struct.Small) align 4 %agg.result) // WIN32: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"() // WIN64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"() // WOA64: define dso_local i32 @"?small_return@@YA?AUSmall@@XZ"() Medium medium_return() { return Medium(); } -// LINUX-LABEL: define{{.*}} void @_Z13medium_returnv(ptr noalias sret(%struct.Medium) align 4 %agg.result) +// LINUX-LABEL: define{{.*}} void @_Z13medium_returnv(ptr dead_on_unwind noalias writable sret(%struct.Medium) align 4 %agg.result) // WIN32: define dso_local i64 @"?medium_return@@YA?AUMedium@@XZ"() // WIN64: define dso_local i64 @"?medium_return@@YA?AUMedium@@XZ"() // WOA64: define dso_local i64 @"?medium_return@@YA?AUMedium@@XZ"() // Returning structs that fit into a register but are not POD. SmallCpp11NotCpp03Pod small_non_pod_return() { return SmallCpp11NotCpp03Pod(); } -// LINUX-LABEL: define{{.*}} void @_Z20small_non_pod_returnv(ptr noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result) -// WIN32: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(ptr noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result) -// WIN64: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(ptr noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result) -// WOA64: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(ptr inreg noalias sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result) +// LINUX-LABEL: define{{.*}} void @_Z20small_non_pod_returnv(ptr dead_on_unwind noalias writable sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result) +// WIN32: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result) +// WIN64: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result) +// WOA64: define dso_local void @"?small_non_pod_return@@YA?AUSmallCpp11NotCpp03Pod@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.SmallCpp11NotCpp03Pod) align 4 %agg.result) SmallWithCtor small_with_ctor_return() { return SmallWithCtor(); } -// LINUX-LABEL: define{{.*}} void @_Z22small_with_ctor_returnv(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result) -// WIN32: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result) -// WIN64: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result) +// LINUX-LABEL: define{{.*}} void @_Z22small_with_ctor_returnv(ptr dead_on_unwind noalias writable sret(%struct.SmallWithCtor) align 4 %agg.result) +// WIN32: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.SmallWithCtor) align 4 %agg.result) +// WIN64: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.SmallWithCtor) align 4 %agg.result) // FIXME: The 'sret' mark here doesn't seem to be enough to convince LLVM to // preserve the hidden sret pointer in R0 across the function. -// WOA: define dso_local arm_aapcs_vfpcc void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result) -// WOA64: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr inreg noalias sret(%struct.SmallWithCtor) align 4 %agg.result) +// WOA: define dso_local arm_aapcs_vfpcc void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.SmallWithCtor) align 4 %agg.result) +// WOA64: define dso_local void @"?small_with_ctor_return@@YA?AUSmallWithCtor@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.SmallWithCtor) align 4 %agg.result) SmallWithDtor small_with_dtor_return() { return SmallWithDtor(); } -// LINUX-LABEL: define{{.*}} void @_Z22small_with_dtor_returnv(ptr noalias sret(%struct.SmallWithDtor) align 4 %agg.result) -// WIN32: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(ptr noalias sret(%struct.SmallWithDtor) align 4 %agg.result) -// WIN64: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(ptr noalias sret(%struct.SmallWithDtor) align 4 %agg.result) -// WOA64: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(ptr inreg noalias sret(%struct.SmallWithDtor) align 4 %agg.result) +// LINUX-LABEL: define{{.*}} void @_Z22small_with_dtor_returnv(ptr dead_on_unwind noalias writable sret(%struct.SmallWithDtor) align 4 %agg.result) +// WIN32: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.SmallWithDtor) align 4 %agg.result) +// WIN64: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.SmallWithDtor) align 4 %agg.result) +// WOA64: define dso_local void @"?small_with_dtor_return@@YA?AUSmallWithDtor@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.SmallWithDtor) align 4 %agg.result) SmallWithVftable small_with_vftable_return() { return SmallWithVftable(); } -// LINUX-LABEL: define{{.*}} void @_Z25small_with_vftable_returnv(ptr noalias sret(%struct.SmallWithVftable) align 4 %agg.result) -// WIN32: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(ptr noalias sret(%struct.SmallWithVftable) align 4 %agg.result) -// WIN64: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(ptr noalias sret(%struct.SmallWithVftable) align 8 %agg.result) -// WOA64: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(ptr inreg noalias sret(%struct.SmallWithVftable) align 8 %agg.result) +// LINUX-LABEL: define{{.*}} void @_Z25small_with_vftable_returnv(ptr dead_on_unwind noalias writable sret(%struct.SmallWithVftable) align 4 %agg.result) +// WIN32: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.SmallWithVftable) align 4 %agg.result) +// WIN64: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.SmallWithVftable) align 8 %agg.result) +// WOA64: define dso_local void @"?small_with_vftable_return@@YA?AUSmallWithVftable@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.SmallWithVftable) align 8 %agg.result) MediumWithCopyCtor medium_with_copy_ctor_return() { return MediumWithCopyCtor(); } -// LINUX-LABEL: define{{.*}} void @_Z28medium_with_copy_ctor_returnv(ptr noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result) -// WIN32: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result) -// WIN64: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result) -// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result) -// WOA64: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr inreg noalias sret(%struct.MediumWithCopyCtor) align 4 %agg.result) +// LINUX-LABEL: define{{.*}} void @_Z28medium_with_copy_ctor_returnv(ptr dead_on_unwind noalias writable sret(%struct.MediumWithCopyCtor) align 4 %agg.result) +// WIN32: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.MediumWithCopyCtor) align 4 %agg.result) +// WIN64: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.MediumWithCopyCtor) align 4 %agg.result) +// WOA: define dso_local arm_aapcs_vfpcc void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.MediumWithCopyCtor) align 4 %agg.result) +// WOA64: define dso_local void @"?medium_with_copy_ctor_return@@YA?AUMediumWithCopyCtor@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.MediumWithCopyCtor) align 4 %agg.result) // Returning a large struct that doesn't fit into a register. Big big_return() { return Big(); } -// LINUX-LABEL: define{{.*}} void @_Z10big_returnv(ptr noalias sret(%struct.Big) align 4 %agg.result) -// WIN32: define dso_local void @"?big_return@@YA?AUBig@@XZ"(ptr noalias sret(%struct.Big) align 4 %agg.result) -// WIN64: define dso_local void @"?big_return@@YA?AUBig@@XZ"(ptr noalias sret(%struct.Big) align 4 %agg.result) -// WOA64: define dso_local void @"?big_return@@YA?AUBig@@XZ"(ptr noalias sret(%struct.Big) align 4 %agg.result) +// LINUX-LABEL: define{{.*}} void @_Z10big_returnv(ptr dead_on_unwind noalias writable sret(%struct.Big) align 4 %agg.result) +// WIN32: define dso_local void @"?big_return@@YA?AUBig@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.Big) align 4 %agg.result) +// WIN64: define dso_local void @"?big_return@@YA?AUBig@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.Big) align 4 %agg.result) +// WOA64: define dso_local void @"?big_return@@YA?AUBig@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.Big) align 4 %agg.result) void small_arg(Small s) {} @@ -197,7 +197,7 @@ void small_arg_with_dtor(SmallWithDtor s) {} // Test that the eligible non-aggregate is passed directly, but returned // indirectly on ARM64 Windows. -// WOA64: define dso_local void @"?small_arg_with_private_member@@YA?AUSmallWithPrivate@@U1@@Z"(ptr inreg noalias sret(%struct.SmallWithPrivate) align 4 %agg.result, i64 %s.coerce) {{.*}} { +// WOA64: define dso_local void @"?small_arg_with_private_member@@YA?AUSmallWithPrivate@@U1@@Z"(ptr dead_on_unwind inreg noalias writable sret(%struct.SmallWithPrivate) align 4 %agg.result, i64 %s.coerce) {{.*}} { SmallWithPrivate small_arg_with_private_member(SmallWithPrivate s) { return s; } // WOA64: define dso_local i32 @"?small_arg_with_small_struct_with_private_member@@YA?AUSmallWithSmallWithPrivate@@U1@@Z"(i64 %s.coerce) {{.*}} { @@ -301,27 +301,27 @@ void pass_ref_field() { class Class { public: Small thiscall_method_small() { return Small(); } - // LINUX: define {{.*}} void @_ZN5Class21thiscall_method_smallEv(ptr noalias sret(%struct.Small) align 4 %agg.result, ptr {{[^,]*}} %this) - // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small@Class@@QAE?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Small) align 4 %agg.result) - // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small@Class@@QEAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Small) align 4 %agg.result) - // WOA64: define linkonce_odr dso_local void @"?thiscall_method_small@Class@@QEAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr inreg noalias sret(%struct.Small) align 4 %agg.result) + // LINUX: define {{.*}} void @_ZN5Class21thiscall_method_smallEv(ptr dead_on_unwind noalias writable sret(%struct.Small) align 4 %agg.result, ptr {{[^,]*}} %this) + // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small@Class@@QAE?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.Small) align 4 %agg.result) + // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small@Class@@QEAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.Small) align 4 %agg.result) + // WOA64: define linkonce_odr dso_local void @"?thiscall_method_small@Class@@QEAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind inreg noalias writable sret(%struct.Small) align 4 %agg.result) SmallWithCtor thiscall_method_small_with_ctor() { return SmallWithCtor(); } - // LINUX: define {{.*}} void @_ZN5Class31thiscall_method_small_with_ctorEv(ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result, ptr {{[^,]*}} %this) - // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small_with_ctor@Class@@QAE?AUSmallWithCtor@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result) - // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small_with_ctor@Class@@QEAA?AUSmallWithCtor@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.SmallWithCtor) align 4 %agg.result) - // WOA64: define linkonce_odr dso_local void @"?thiscall_method_small_with_ctor@Class@@QEAA?AUSmallWithCtor@@XZ"(ptr {{[^,]*}} %this, ptr inreg noalias sret(%struct.SmallWithCtor) align 4 %agg.result) + // LINUX: define {{.*}} void @_ZN5Class31thiscall_method_small_with_ctorEv(ptr dead_on_unwind noalias writable sret(%struct.SmallWithCtor) align 4 %agg.result, ptr {{[^,]*}} %this) + // WIN32: define {{.*}} x86_thiscallcc void @"?thiscall_method_small_with_ctor@Class@@QAE?AUSmallWithCtor@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.SmallWithCtor) align 4 %agg.result) + // WIN64: define linkonce_odr dso_local void @"?thiscall_method_small_with_ctor@Class@@QEAA?AUSmallWithCtor@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.SmallWithCtor) align 4 %agg.result) + // WOA64: define linkonce_odr dso_local void @"?thiscall_method_small_with_ctor@Class@@QEAA?AUSmallWithCtor@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind inreg noalias writable sret(%struct.SmallWithCtor) align 4 %agg.result) Small __cdecl cdecl_method_small() { return Small(); } - // LINUX: define {{.*}} void @_ZN5Class18cdecl_method_smallEv(ptr noalias sret(%struct.Small) align 4 %agg.result, ptr {{[^,]*}} %this) - // WIN32: define {{.*}} void @"?cdecl_method_small@Class@@QAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Small) align 4 %agg.result) - // WIN64: define linkonce_odr dso_local void @"?cdecl_method_small@Class@@QEAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Small) align 4 %agg.result) + // LINUX: define {{.*}} void @_ZN5Class18cdecl_method_smallEv(ptr dead_on_unwind noalias writable sret(%struct.Small) align 4 %agg.result, ptr {{[^,]*}} %this) + // WIN32: define {{.*}} void @"?cdecl_method_small@Class@@QAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.Small) align 4 %agg.result) + // WIN64: define linkonce_odr dso_local void @"?cdecl_method_small@Class@@QEAA?AUSmall@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.Small) align 4 %agg.result) Big __cdecl cdecl_method_big() { return Big(); } - // LINUX: define {{.*}} void @_ZN5Class16cdecl_method_bigEv(ptr noalias sret(%struct.Big) align 4 %agg.result, ptr {{[^,]*}} %this) - // WIN32: define {{.*}} void @"?cdecl_method_big@Class@@QAA?AUBig@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Big) align 4 %agg.result) - // WIN64: define linkonce_odr dso_local void @"?cdecl_method_big@Class@@QEAA?AUBig@@XZ"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.Big) align 4 %agg.result) - // WOA64: define linkonce_odr dso_local void @"?cdecl_method_big@Class@@QEAA?AUBig@@XZ"(ptr {{[^,]*}} %this, ptr inreg noalias sret(%struct.Big) align 4 %agg.result) + // LINUX: define {{.*}} void @_ZN5Class16cdecl_method_bigEv(ptr dead_on_unwind noalias writable sret(%struct.Big) align 4 %agg.result, ptr {{[^,]*}} %this) + // WIN32: define {{.*}} void @"?cdecl_method_big@Class@@QAA?AUBig@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.Big) align 4 %agg.result) + // WIN64: define linkonce_odr dso_local void @"?cdecl_method_big@Class@@QEAA?AUBig@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.Big) align 4 %agg.result) + // WOA64: define linkonce_odr dso_local void @"?cdecl_method_big@Class@@QEAA?AUBig@@XZ"(ptr {{[^,]*}} %this, ptr dead_on_unwind inreg noalias writable sret(%struct.Big) align 4 %agg.result) void thiscall_method_arg(Empty s) {} // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Empty(ptr {{[^,]*}} %this) diff --git a/clang/test/CodeGenCXX/microsoft-abi-unknown-arch.cpp b/clang/test/CodeGenCXX/microsoft-abi-unknown-arch.cpp index 3045e90777cbc..9e37e71e257fd 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-unknown-arch.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-unknown-arch.cpp @@ -18,4 +18,4 @@ A B::foo(A x) { return x; } -// CHECK-LABEL: define{{.*}} void @"?foo@B@@QEAA?AUA@@U2@@Z"(ptr {{[^,]*}} %this, ptr noalias sret(%struct.A) align 4 %agg.result, ptr noundef %x) +// CHECK-LABEL: define{{.*}} void @"?foo@B@@QEAA?AUA@@U2@@Z"(ptr {{[^,]*}} %this, ptr dead_on_unwind noalias writable sret(%struct.A) align 4 %agg.result, ptr noundef %x) diff --git a/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp b/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp index 2a29a080d025a..615a2e34d7a2b 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp @@ -65,7 +65,7 @@ void f(C *c) { // CHECK-LABEL: define dso_local void @"?f@sret@@YAXPAUC@1@@Z"(ptr noundef %c) // CHECK: call x86_thiscallcc noundef i32 @"??_9C@sret@@$BA@AE"(ptr {{[^,]*}} %{{.*}}) -// CHECK: call x86_thiscallcc void @"??_9C@sret@@$BA@AE"(ptr {{[^,]*}} %{{.*}}, ptr sret(%"struct.sret::Big") align 4 %{{.*}}) +// CHECK: call x86_thiscallcc void @"??_9C@sret@@$BA@AE"(ptr {{[^,]*}} %{{.*}}, ptr dead_on_unwind writable sret(%"struct.sret::Big") align 4 %{{.*}}) // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"??_9C@sret@@$BA@AE"(ptr noundef %this, ...) {{.*}} comdat // CHECK: musttail call x86_thiscallcc void (ptr, ...) %{{.*}}(ptr noundef %{{.*}}, ...) diff --git a/clang/test/CodeGenCXX/ms-thread_local.cpp b/clang/test/CodeGenCXX/ms-thread_local.cpp index a6c62967f23de..cb0e8720c19b8 100644 --- a/clang/test/CodeGenCXX/ms-thread_local.cpp +++ b/clang/test/CodeGenCXX/ms-thread_local.cpp @@ -29,9 +29,9 @@ thread_local A b; // CHECK-LD-LABEL: declare dso_local void @__dyn_tls_on_demand_init() // CHECK-LEGACY-NOT: declare dso_local void @__dyn_tls_on_demand_init() -// CHECK-LABEL: define dso_local void @"?f@@YA?AUA@@XZ"(ptr noalias sret(%struct.A) align 1 %agg.result) +// CHECK-LABEL: define dso_local void @"?f@@YA?AUA@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.A) align 1 %agg.result) // CHECK: call void @__dyn_tls_on_demand_init() -// CHECK-LD-LABEL: define dso_local void @"?f@@YA?AUA@@XZ"(ptr noalias sret(%struct.A) align 1 %agg.result) +// CHECK-LD-LABEL: define dso_local void @"?f@@YA?AUA@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.A) align 1 %agg.result) // CHECK-LD: call void @__dyn_tls_on_demand_init() // CHECK-LEGACY-NOT: call void @__dyn_tls_on_demand_init() diff --git a/clang/test/CodeGenCXX/nrvo.cpp b/clang/test/CodeGenCXX/nrvo.cpp index 975cf6ee1b66d..33dc4cf9dbc8d 100644 --- a/clang/test/CodeGenCXX/nrvo.cpp +++ b/clang/test/CodeGenCXX/nrvo.cpp @@ -1059,7 +1059,7 @@ X test8(bool b) { // CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 // CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 // CHECK-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 -// CHECK-NEXT: call void @_ZN1YIiE1fEv(ptr sret([[STRUCT_Y]]) align 1 [[TMP]]) +// CHECK-NEXT: call void @_ZN1YIiE1fEv(ptr dead_on_unwind writable sret([[STRUCT_Y]]) align 1 [[TMP]]) // CHECK-NEXT: call void @llvm.trap() // CHECK-NEXT: unreachable // @@ -1068,7 +1068,7 @@ X test8(bool b) { // CHECK-EH-03-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 // CHECK-EH-03-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 // CHECK-EH-03-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 -// CHECK-EH-03-NEXT: call void @_ZN1YIiE1fEv(ptr sret([[STRUCT_Y]]) align 1 [[TMP]]) +// CHECK-EH-03-NEXT: call void @_ZN1YIiE1fEv(ptr dead_on_unwind writable sret([[STRUCT_Y]]) align 1 [[TMP]]) // CHECK-EH-03-NEXT: call void @llvm.trap() // CHECK-EH-03-NEXT: unreachable // @@ -1077,7 +1077,7 @@ X test8(bool b) { // CHECK-EH-11-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 // CHECK-EH-11-NEXT: [[TMP:%.*]] = alloca [[STRUCT_Y:%.*]], align 1 // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4 -// CHECK-EH-11-NEXT: call void @_ZN1YIiE1fEv(ptr sret([[STRUCT_Y]]) align 1 [[TMP]]) +// CHECK-EH-11-NEXT: call void @_ZN1YIiE1fEv(ptr dead_on_unwind writable sret([[STRUCT_Y]]) align 1 [[TMP]]) // CHECK-EH-11-NEXT: call void @llvm.trap() // CHECK-EH-11-NEXT: unreachable // @@ -1915,7 +1915,7 @@ X test15(bool b) { // http://wg21.link/p2025r2#ex-15 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[X]]) // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_ANON]], ptr [[REF_TMP]], i32 0, i32 0 // CHECK-EH-11-NEXT: store ptr [[X]], ptr [[TMP0]], align 4 -// CHECK-EH-11-NEXT: invoke void @"_ZZ6test16vENK3$_0clEv"(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) +// CHECK-EH-11-NEXT: invoke void @"_ZZ6test16vENK3$_0clEv"(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK-EH-11: invoke.cont: // CHECK-EH-11-NEXT: invoke void @_Z8ConsumeX1X(ptr noundef [[AGG_TMP]]) @@ -2530,7 +2530,7 @@ X test18(int i) { // http://wg21.link/p2025r2#ex-11 // CHECK-EH-11-NEXT: call void @_ZN1XC1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_RESULT]]) // CHECK-EH-11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [[CLASS_ANON_0]], ptr [[REF_TMP]], i32 0, i32 0 // CHECK-EH-11-NEXT: store ptr [[AGG_RESULT]], ptr [[TMP0]], align 4 -// CHECK-EH-11-NEXT: invoke void @"_ZZ6test19vENK3$_0clEv"(ptr sret([[CLASS_X]]) align 1 [[L]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) +// CHECK-EH-11-NEXT: invoke void @"_ZZ6test19vENK3$_0clEv"(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[L]], ptr noundef nonnull align 4 dereferenceable(4) [[REF_TMP]]) // CHECK-EH-11-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] // CHECK-EH-11: invoke.cont: // CHECK-EH-11-NEXT: store i1 true, ptr [[NRVO]], align 1 @@ -2584,9 +2584,9 @@ X test20() { // http://wg21.link/p2025r2#ex-18 // CHECK-EH-11-NEXT: entry: // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 1 // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1 -// CHECK-EH-11-NEXT: call void @_Z6test20ILb1EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]]) +// CHECK-EH-11-NEXT: call void @_Z6test20ILb1EE1Xv(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]]) // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR6]] -// CHECK-EH-11-NEXT: call void @_Z6test20ILb0EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]]) +// CHECK-EH-11-NEXT: call void @_Z6test20ILb0EE1Xv(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]]) // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR6]] // CHECK-EH-11-NEXT: ret void // @@ -2934,9 +2934,9 @@ X test25() { // CHECK-EH-11-NEXT: entry: // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED:%.*]] = alloca [[CLASS_X:%.*]], align 1 // CHECK-EH-11-NEXT: [[AGG_TMP_ENSURED1:%.*]] = alloca [[CLASS_X]], align 1 -// CHECK-EH-11-NEXT: call void @_Z6test25ILb1EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]]) +// CHECK-EH-11-NEXT: call void @_Z6test25ILb1EE1Xv(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED]]) // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED]]) #[[ATTR6]] -// CHECK-EH-11-NEXT: call void @_Z6test25ILb0EE1Xv(ptr sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]]) +// CHECK-EH-11-NEXT: call void @_Z6test25ILb0EE1Xv(ptr dead_on_unwind writable sret([[CLASS_X]]) align 1 [[AGG_TMP_ENSURED1]]) // CHECK-EH-11-NEXT: call void @_ZN1XD1Ev(ptr noundef nonnull align 1 dereferenceable(1) [[AGG_TMP_ENSURED1]]) #[[ATTR6]] // CHECK-EH-11-NEXT: ret void // diff --git a/clang/test/CodeGenCXX/pass-by-value-noalias.cpp b/clang/test/CodeGenCXX/pass-by-value-noalias.cpp index 765a6fb66a72b..773cf6b81c3b2 100644 --- a/clang/test/CodeGenCXX/pass-by-value-noalias.cpp +++ b/clang/test/CodeGenCXX/pass-by-value-noalias.cpp @@ -58,8 +58,8 @@ A *p; // NO_NOALIAS: define{{.*}} void @_Z4take1A(ptr noundef %arg) void take(A arg) {} -// WITH_NOALIAS: define{{.*}} void @_Z7CreateAPP1A(ptr noalias sret(%struct.A) align 1 %agg.result, ptr noundef %where) -// NO_NOALIAS: define{{.*}} void @_Z7CreateAPP1A(ptr noalias sret(%struct.A) align 1 %agg.result, ptr noundef %where) +// WITH_NOALIAS: define{{.*}} void @_Z7CreateAPP1A(ptr dead_on_unwind noalias writable sret(%struct.A) align 1 %agg.result, ptr noundef %where) +// NO_NOALIAS: define{{.*}} void @_Z7CreateAPP1A(ptr dead_on_unwind noalias writable sret(%struct.A) align 1 %agg.result, ptr noundef %where) A CreateA(A **where) { A justlikethis; *where = &justlikethis; //Escaped pointer 2 (should also be UB, then) diff --git a/clang/test/CodeGenCXX/regcall.cpp b/clang/test/CodeGenCXX/regcall.cpp index b47a2125d7873..1ff7597e9deef 100644 --- a/clang/test/CodeGenCXX/regcall.cpp +++ b/clang/test/CodeGenCXX/regcall.cpp @@ -74,8 +74,8 @@ bool __regcall operator ==(const test_class&, const test_class&){ --x; return fa // CHECK-WIN32-DAG: define dso_local x86_regcallcc noundef zeroext i1 @"??8@Yw_NABVtest_class@@0@Z" test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};} -// CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(ptr noalias sret(%class.test_class) align 4 %agg.result, i64 noundef %0) -// CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(ptr inreg noalias sret(%class.test_class) align 4 %agg.result, i64 noundef %0) +// CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(ptr dead_on_unwind noalias writable sret(%class.test_class) align 4 %agg.result, i64 noundef %0) +// CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(ptr dead_on_unwind inreg noalias writable sret(%class.test_class) align 4 %agg.result, i64 noundef %0) // CHECK-WIN64-DAG: ??__K_test_class@@Yw?AVtest_class@@_K@Z" // CHECK-WIN32-DAG: ??__K_test_class@@Yw?AVtest_class@@_K@Z" @@ -99,8 +99,8 @@ void force_gen() { long double _Complex __regcall foo(long double _Complex f) { return f; } -// CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall3__fooCe(ptr noalias sret({ x86_fp80, x86_fp80 }) align 16 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 %f) -// CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall3__fooCe(ptr inreg noalias sret({ x86_fp80, x86_fp80 }) align 4 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 4 %f) +// CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall3__fooCe(ptr dead_on_unwind noalias writable sret({ x86_fp80, x86_fp80 }) align 16 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 %f) +// CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall3__fooCe(ptr dead_on_unwind inreg noalias writable sret({ x86_fp80, x86_fp80 }) align 4 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 4 %f) // CHECK-WIN64-DAG: define dso_local x86_regcallcc noundef { double, double } @"?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double noundef %f.0, double noundef %f.1) // CHECK-WIN32-DAG: define dso_local x86_regcallcc noundef { double, double } @"?foo@@YwU?$_Complex@O@__clang@@U12@@Z"(double noundef %f.0, double noundef %f.1) diff --git a/clang/test/CodeGenCXX/regcall4.cpp b/clang/test/CodeGenCXX/regcall4.cpp index 7c35db36e1053..2ecd5b4951c75 100644 --- a/clang/test/CodeGenCXX/regcall4.cpp +++ b/clang/test/CodeGenCXX/regcall4.cpp @@ -74,8 +74,8 @@ bool __regcall operator ==(const test_class&, const test_class&){ --x; return fa // CHECK-WIN32-DAG: define dso_local x86_regcallcc noundef zeroext i1 @"??8@Yx_NABVtest_class@@0@Z" test_class __regcall operator""_test_class (unsigned long long) { ++x; return test_class{};} -// CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(ptr noalias sret(%class.test_class) align 4 %agg.result, i64 noundef %0) -// CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(ptr inreg noalias sret(%class.test_class) align 4 %agg.result, i64 noundef %0) +// CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(ptr dead_on_unwind noalias writable sret(%class.test_class) align 4 %agg.result, i64 noundef %0) +// CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Zli11_test_classy(ptr dead_on_unwind inreg noalias writable sret(%class.test_class) align 4 %agg.result, i64 noundef %0) // CHECK-WIN64-DAG: ??__K_test_class@@Yx?AVtest_class@@_K@Z" // CHECK-WIN32-DAG: ??__K_test_class@@Yx?AVtest_class@@_K@Z" @@ -99,8 +99,8 @@ void force_gen() { long double _Complex __regcall foo(long double _Complex f) { return f; } -// CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall4__fooCe(ptr noalias sret({ x86_fp80, x86_fp80 }) align 16 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 %f) -// CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall4__fooCe(ptr inreg noalias sret({ x86_fp80, x86_fp80 }) align 4 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 4 %f) +// CHECK-LIN64-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall4__fooCe(ptr dead_on_unwind noalias writable sret({ x86_fp80, x86_fp80 }) align 16 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 16 %f) +// CHECK-LIN32-DAG: define{{.*}} x86_regcallcc void @_Z15__regcall4__fooCe(ptr dead_on_unwind inreg noalias writable sret({ x86_fp80, x86_fp80 }) align 4 %agg.result, ptr noundef byval({ x86_fp80, x86_fp80 }) align 4 %f) // CHECK-WIN64-DAG: define dso_local x86_regcallcc noundef { double, double } @"?foo@@YxU?$_Complex@O@__clang@@U12@@Z"(double noundef %f.0, double noundef %f.1) // CHECK-WIN32-DAG: define dso_local x86_regcallcc noundef { double, double } @"?foo@@YxU?$_Complex@O@__clang@@U12@@Z"(double noundef %f.0, double noundef %f.1) diff --git a/clang/test/CodeGenCXX/stack-reuse-miscompile.cpp b/clang/test/CodeGenCXX/stack-reuse-miscompile.cpp index dbeea5e32cfb8..50a8d167f5b77 100644 --- a/clang/test/CodeGenCXX/stack-reuse-miscompile.cpp +++ b/clang/test/CodeGenCXX/stack-reuse-miscompile.cpp @@ -36,7 +36,7 @@ const char * f(S s) // CHECK: call void @llvm.lifetime.start.p0(i64 16, ptr [[T3]]) // CHECK: [[T5:%.*]] = call noundef ptr @_ZN1TC1E1S(ptr {{[^,]*}} [[T3]], [2 x i32] %{{.*}}) // -// CHECK: call void @_ZNK1T6concatERKS_(ptr sret(%class.T) align 4 [[T1]], ptr {{[^,]*}} [[T2]], ptr noundef nonnull align 4 dereferenceable(16) [[T3]]) +// CHECK: call void @_ZNK1T6concatERKS_(ptr dead_on_unwind writable sret(%class.T) align 4 [[T1]], ptr {{[^,]*}} [[T2]], ptr noundef nonnull align 4 dereferenceable(16) [[T3]]) // CHECK: [[T6:%.*]] = call noundef ptr @_ZNK1T3strEv(ptr {{[^,]*}} [[T1]]) // // CHECK: call void @llvm.lifetime.end.p0( diff --git a/clang/test/CodeGenCXX/stack-reuse.cpp b/clang/test/CodeGenCXX/stack-reuse.cpp index e2412a55c1f62..ca73781b79ec1 100644 --- a/clang/test/CodeGenCXX/stack-reuse.cpp +++ b/clang/test/CodeGenCXX/stack-reuse.cpp @@ -135,7 +135,7 @@ int large_combiner_test(S_large s) { // CHECK: [[T2:%.*]] = alloca %struct.Combiner // CHECK: [[T1:%.*]] = alloca %struct.Combiner // CHECK: [[T3:%.*]] = call noundef ptr @_ZN8CombinerC1E7S_large(ptr {{[^,]*}} [[T1]], [9 x i32] %s.coerce) -// CHECK: call void @_ZN8Combiner1fEv(ptr nonnull sret(%struct.Combiner) align 4 [[T2]], ptr {{[^,]*}} [[T1]]) +// CHECK: call void @_ZN8Combiner1fEv(ptr dead_on_unwind nonnull writable sret(%struct.Combiner) align 4 [[T2]], ptr {{[^,]*}} [[T1]]) // CHECK: [[T5:%.*]] = load i32, ptr [[T2]] // CHECK: ret i32 [[T5]] diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp index c5adb42a6f173..9f29d3b732783 100644 --- a/clang/test/CodeGenCXX/temporaries.cpp +++ b/clang/test/CodeGenCXX/temporaries.cpp @@ -414,13 +414,13 @@ namespace Elision { // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[I]]) A i = (foo(), A()); - // CHECK-NEXT: call void @_ZN7Elision4fooAEv(ptr sret([[A]]) align 8 [[T0]]) + // CHECK-NEXT: call void @_ZN7Elision4fooAEv(ptr dead_on_unwind writable sret([[A]]) align 8 [[T0]]) // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[J]]) // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[T0]]) A j = (fooA(), A()); // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[T1]]) - // CHECK-NEXT: call void @_ZN7Elision4fooAEv(ptr sret([[A]]) align 8 [[K]]) + // CHECK-NEXT: call void @_ZN7Elision4fooAEv(ptr dead_on_unwind writable sret([[A]]) align 8 [[K]]) // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[T1]]) A k = (A(), fooA()); @@ -447,7 +447,7 @@ namespace Elision { // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[I]]) } - // CHECK: define{{.*}} void @_ZN7Elision5test2Ev(ptr noalias sret([[A]]) align 8 + // CHECK: define{{.*}} void @_ZN7Elision5test2Ev(ptr dead_on_unwind noalias writable sret([[A]]) align 8 A test2() { // CHECK: call void @_ZN7Elision3fooEv() // CHECK-NEXT: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[RET:%.*]]) @@ -455,7 +455,7 @@ namespace Elision { return (foo(), A()); } - // CHECK: define{{.*}} void @_ZN7Elision5test3EiNS_1AE(ptr noalias sret([[A]]) align 8 + // CHECK: define{{.*}} void @_ZN7Elision5test3EiNS_1AE(ptr dead_on_unwind noalias writable sret([[A]]) align 8 A test3(int v, A x) { if (v < 5) // CHECK: call void @_ZN7Elision1AC1Ev(ptr {{[^,]*}} [[RET:%.*]]) @@ -495,7 +495,7 @@ namespace Elision { // CHECK: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[X]]) } - // CHECK: define{{.*}} void @_ZN7Elision5test5Ev(ptr noalias sret([[A]]) align 8 + // CHECK: define{{.*}} void @_ZN7Elision5test5Ev(ptr dead_on_unwind noalias writable sret([[A]]) align 8 struct B { A a; B(); }; A test5() { // CHECK: [[AT0:%.*]] = alloca [[A]], align 8 @@ -533,7 +533,7 @@ namespace Elision { void test6(const C *x) { // CHECK: [[T0:%.*]] = alloca [[A]], align 8 // CHECK: [[X:%.*]] = load ptr, ptr {{%.*}}, align 8 - // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv(ptr sret([[A]]) align 8 [[T0]], ptr {{[^,]*}} [[X]]) + // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv(ptr dead_on_unwind writable sret([[A]]) align 8 [[T0]], ptr {{[^,]*}} [[X]]) // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv(ptr {{[^,]*}} [[T0]]) // CHECK-NEXT: call void @_ZN7Elision1AD1Ev(ptr {{[^,]*}} [[T0]]) // CHECK-NEXT: ret void diff --git a/clang/test/CodeGenCXX/thiscall-struct-return.cpp b/clang/test/CodeGenCXX/thiscall-struct-return.cpp index c29ec56b41c1a..7802ed4b18ebd 100644 --- a/clang/test/CodeGenCXX/thiscall-struct-return.cpp +++ b/clang/test/CodeGenCXX/thiscall-struct-return.cpp @@ -34,8 +34,8 @@ void test( void ) { // CHECK: call void @_ZN1CC1Ev(ptr {{[^,]*}} [[C:%.+]]) C c; -// CHECK: call x86_thiscallcc void @_ZNK1C5SmallEv(ptr sret(%struct.S) align 4 %{{.+}}, ptr {{[^,]*}} [[C]]) +// CHECK: call x86_thiscallcc void @_ZNK1C5SmallEv(ptr dead_on_unwind writable sret(%struct.S) align 4 %{{.+}}, ptr {{[^,]*}} [[C]]) (void)c.Small(); -// CHECK: call x86_thiscallcc void @_ZNK1C6MediumEv(ptr sret(%struct.M) align 4 %{{.+}}, ptr {{[^,]*}} [[C]]) +// CHECK: call x86_thiscallcc void @_ZNK1C6MediumEv(ptr dead_on_unwind writable sret(%struct.M) align 4 %{{.+}}, ptr {{[^,]*}} [[C]]) (void)c.Medium(); } diff --git a/clang/test/CodeGenCXX/thunk-returning-memptr.cpp b/clang/test/CodeGenCXX/thunk-returning-memptr.cpp index aaa5c8605f23e..99ef76f91cecf 100644 --- a/clang/test/CodeGenCXX/thunk-returning-memptr.cpp +++ b/clang/test/CodeGenCXX/thunk-returning-memptr.cpp @@ -23,5 +23,5 @@ C::C() {} // Because of the tail call, the return value cannot be copied into a local // alloca. (PR39901) -// CHECK-LABEL: define linkonce_odr void @_ZThn4_N1C1fEv(ptr noalias sret({ i32, i32 }) align 4 %agg.result, ptr noundef %this) -// CHECK: tail call void @_ZN1C1fEv(ptr sret({ i32, i32 }) align 4 %agg.result +// CHECK-LABEL: define linkonce_odr void @_ZThn4_N1C1fEv(ptr dead_on_unwind noalias writable sret({ i32, i32 }) align 4 %agg.result, ptr noundef %this) +// CHECK: tail call void @_ZN1C1fEv(ptr dead_on_unwind writable sret({ i32, i32 }) align 4 %agg.result diff --git a/clang/test/CodeGenCXX/trivial_abi.cpp b/clang/test/CodeGenCXX/trivial_abi.cpp index 3249df129157f..3012b0f2bc33d 100644 --- a/clang/test/CodeGenCXX/trivial_abi.cpp +++ b/clang/test/CodeGenCXX/trivial_abi.cpp @@ -151,7 +151,7 @@ void testIgnoredSmall() { void testParamLarge(Large a) noexcept { } -// CHECK: define{{.*}} void @_Z15testReturnLargev(ptr noalias sret(%[[STRUCT_LARGE]]) align 8 %[[AGG_RESULT:.*]]) +// CHECK: define{{.*}} void @_Z15testReturnLargev(ptr dead_on_unwind noalias writable sret(%[[STRUCT_LARGE]]) align 8 %[[AGG_RESULT:.*]]) // CHECK: %[[CALL:.*]] = call noundef ptr @_ZN5LargeC1Ev(ptr {{[^,]*}} %[[AGG_RESULT]]) // CHECK: ret void // CHECK: } @@ -178,7 +178,7 @@ void testCallLarge0() { // CHECK: define{{.*}} void @_Z14testCallLarge1v() // CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_LARGE:.*]], align 8 -// CHECK: call void @_Z15testReturnLargev(ptr sret(%[[STRUCT_LARGE]]) align 8 %[[AGG_TMP]]) +// CHECK: call void @_Z15testReturnLargev(ptr dead_on_unwind writable sret(%[[STRUCT_LARGE]]) align 8 %[[AGG_TMP]]) // CHECK: call void @_Z14testParamLarge5Large(ptr noundef %[[AGG_TMP]]) // CHECK: ret void // CHECK: } @@ -189,7 +189,7 @@ void testCallLarge1() { // CHECK: define{{.*}} void @_Z16testIgnoredLargev() // CHECK: %[[AGG_TMP_ENSURED:.*]] = alloca %[[STRUCT_LARGE:.*]], align 8 -// CHECK: call void @_Z15testReturnLargev(ptr sret(%[[STRUCT_LARGE]]) align 8 %[[AGG_TMP_ENSURED]]) +// CHECK: call void @_Z15testReturnLargev(ptr dead_on_unwind writable sret(%[[STRUCT_LARGE]]) align 8 %[[AGG_TMP_ENSURED]]) // CHECK: %[[CALL:.*]] = call noundef ptr @_ZN5LargeD1Ev(ptr {{[^,]*}} %[[AGG_TMP_ENSURED]]) // CHECK: ret void // CHECK: } @@ -210,7 +210,7 @@ Trivial testReturnHasTrivial() { return t; } -// CHECK: define{{.*}} void @_Z23testReturnHasNonTrivialv(ptr noalias sret(%[[STRUCT_NONTRIVIAL:.*]]) align 4 %[[AGG_RESULT:.*]]) +// CHECK: define{{.*}} void @_Z23testReturnHasNonTrivialv(ptr dead_on_unwind noalias writable sret(%[[STRUCT_NONTRIVIAL:.*]]) align 4 %[[AGG_RESULT:.*]]) // CHECK: %[[CALL:.*]] = call noundef ptr @_ZN10NonTrivialC1Ev(ptr {{[^,]*}} %[[AGG_RESULT]]) // CHECK: ret void // CHECK: } diff --git a/clang/test/CodeGenCXX/unknown-anytype.cpp b/clang/test/CodeGenCXX/unknown-anytype.cpp index 862b8fe8b66dd..ade9a6482d75c 100644 --- a/clang/test/CodeGenCXX/unknown-anytype.cpp +++ b/clang/test/CodeGenCXX/unknown-anytype.cpp @@ -70,7 +70,7 @@ struct Test7 { }; extern "C" __unknown_anytype test7_any(int); Test7 test7() { - // COMMON: call void @test7_any(ptr sret({{%.*}}) align 1 {{%.*}}, i32 noundef 5) + // COMMON: call void @test7_any(ptr dead_on_unwind writable sret({{%.*}}) align 1 {{%.*}}, i32 noundef 5) return (Test7) test7_any(5); } diff --git a/clang/test/CodeGenCXX/wasm-args-returns.cpp b/clang/test/CodeGenCXX/wasm-args-returns.cpp index 090ca9a99756f..e80dfefedece1 100644 --- a/clang/test/CodeGenCXX/wasm-args-returns.cpp +++ b/clang/test/CodeGenCXX/wasm-args-returns.cpp @@ -30,52 +30,52 @@ struct two_fields { double d, e; }; test(two_fields); -// CHECK: define void @_Z7forward10two_fields(ptr noalias nocapture writeonly sret(%struct.two_fields) align 8 %{{.*}}, ptr nocapture readonly byval(%struct.two_fields) align 8 %{{.*}}) +// CHECK: define void @_Z7forward10two_fields(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.two_fields) align 8 %{{.*}}, ptr nocapture readonly byval(%struct.two_fields) align 8 %{{.*}}) // // CHECK: define void @_Z15test_two_fieldsv() // CHECK: %[[tmp:.*]] = alloca %struct.two_fields, align 8 -// CHECK: call void @_Z14def_two_fieldsv(ptr nonnull sret(%struct.two_fields) align 8 %[[tmp]]) +// CHECK: call void @_Z14def_two_fieldsv(ptr dead_on_unwind nonnull writable sret(%struct.two_fields) align 8 %[[tmp]]) // CHECK: call void @_Z3use10two_fields(ptr nonnull byval(%struct.two_fields) align 8 %[[tmp]]) // CHECK: ret void // // CHECK: declare void @_Z3use10two_fields(ptr byval(%struct.two_fields) align 8) -// CHECK: declare void @_Z14def_two_fieldsv(ptr sret(%struct.two_fields) align 8) +// CHECK: declare void @_Z14def_two_fieldsv(ptr dead_on_unwind writable sret(%struct.two_fields) align 8) struct copy_ctor { double d; copy_ctor(copy_ctor const &); }; test(copy_ctor); -// CHECK: define void @_Z7forward9copy_ctor(ptr noalias {{[^,]*}} sret(%struct.copy_ctor) align 8 %{{.*}}, ptr nonnull %{{.*}}) +// CHECK: define void @_Z7forward9copy_ctor(ptr dead_on_unwind noalias {{[^,]*}} sret(%struct.copy_ctor) align 8 %{{.*}}, ptr nonnull %{{.*}}) // // CHECK: declare ptr @_ZN9copy_ctorC1ERKS_(ptr {{[^,]*}} returned {{[^,]*}}, ptr nonnull align 8 dereferenceable(8)) // // CHECK: define void @_Z14test_copy_ctorv() // CHECK: %[[tmp:.*]] = alloca %struct.copy_ctor, align 8 -// CHECK: call void @_Z13def_copy_ctorv(ptr nonnull sret(%struct.copy_ctor) align 8 %[[tmp]]) +// CHECK: call void @_Z13def_copy_ctorv(ptr dead_on_unwind nonnull writable sret(%struct.copy_ctor) align 8 %[[tmp]]) // CHECK: call void @_Z3use9copy_ctor(ptr nonnull %[[tmp]]) // CHECK: ret void // // CHECK: declare void @_Z3use9copy_ctor(ptr) -// CHECK: declare void @_Z13def_copy_ctorv(ptr sret(%struct.copy_ctor) align 8) +// CHECK: declare void @_Z13def_copy_ctorv(ptr dead_on_unwind writable sret(%struct.copy_ctor) align 8) struct __attribute__((aligned(16))) aligned_copy_ctor { double d, e; aligned_copy_ctor(aligned_copy_ctor const &); }; test(aligned_copy_ctor); -// CHECK: define void @_Z7forward17aligned_copy_ctor(ptr noalias {{[^,]*}} sret(%struct.aligned_copy_ctor) align 16 %{{.*}}, ptr nonnull %{{.*}}) +// CHECK: define void @_Z7forward17aligned_copy_ctor(ptr dead_on_unwind noalias {{[^,]*}} sret(%struct.aligned_copy_ctor) align 16 %{{.*}}, ptr nonnull %{{.*}}) // // CHECK: declare ptr @_ZN17aligned_copy_ctorC1ERKS_(ptr {{[^,]*}} returned {{[^,]*}}, ptr nonnull align 16 dereferenceable(16)) // // CHECK: define void @_Z22test_aligned_copy_ctorv() // CHECK: %[[tmp:.*]] = alloca %struct.aligned_copy_ctor, align 16 -// CHECK: call void @_Z21def_aligned_copy_ctorv(ptr nonnull sret(%struct.aligned_copy_ctor) align 16 %[[tmp]]) +// CHECK: call void @_Z21def_aligned_copy_ctorv(ptr dead_on_unwind nonnull writable sret(%struct.aligned_copy_ctor) align 16 %[[tmp]]) // CHECK: call void @_Z3use17aligned_copy_ctor(ptr nonnull %[[tmp]]) // CHECK: ret void // // CHECK: declare void @_Z3use17aligned_copy_ctor(ptr) -// CHECK: declare void @_Z21def_aligned_copy_ctorv(ptr sret(%struct.aligned_copy_ctor) align 16) +// CHECK: declare void @_Z21def_aligned_copy_ctorv(ptr dead_on_unwind writable sret(%struct.aligned_copy_ctor) align 16) struct empty {}; test(empty); diff --git a/clang/test/CodeGenCXX/x86_32-arguments.cpp b/clang/test/CodeGenCXX/x86_32-arguments.cpp index 7388b2fcfe6cd..c071548327e8d 100644 --- a/clang/test/CodeGenCXX/x86_32-arguments.cpp +++ b/clang/test/CodeGenCXX/x86_32-arguments.cpp @@ -6,7 +6,7 @@ struct S { short s; }; -// CHECK-LABEL: define{{.*}} void @_Z1fv(ptr noalias sret(%struct.S) align 2 % +// CHECK-LABEL: define{{.*}} void @_Z1fv(ptr dead_on_unwind noalias writable sret(%struct.S) align 2 % S f() { return S(); } // CHECK-LABEL: define{{.*}} void @_Z1f1S(ptr noundef %0) void f(S) { } @@ -18,7 +18,7 @@ class C { double c; }; -// CHECK-LABEL: define{{.*}} void @_Z1gv(ptr noalias sret(%class.C) align 4 % +// CHECK-LABEL: define{{.*}} void @_Z1gv(ptr dead_on_unwind noalias writable sret(%class.C) align 4 % C g() { return C(); } // CHECK-LABEL: define{{.*}} void @_Z1f1C(ptr noundef %0) @@ -103,13 +103,13 @@ struct s7_1 { double x; }; struct s7 : s7_0, s7_1 { }; s7 f7() { return s7(); } -// CHECK-LABEL: define{{.*}} void @_Z2f8v(ptr noalias sret(%struct.s8) align 4 %agg.result) +// CHECK-LABEL: define{{.*}} void @_Z2f8v(ptr dead_on_unwind noalias writable sret(%struct.s8) align 4 %agg.result) struct s8_0 { }; struct s8_1 { double x; }; struct s8 { s8_0 a; s8_1 b; }; s8 f8() { return s8(); } -// CHECK-LABEL: define{{.*}} void @_Z2f9v(ptr noalias sret(%struct.s9) align 4 %agg.result) +// CHECK-LABEL: define{{.*}} void @_Z2f9v(ptr dead_on_unwind noalias writable sret(%struct.s9) align 4 %agg.result) struct s9_0 { unsigned : 0; }; struct s9_1 { double x; }; struct s9 { s9_0 a; s9_1 b; }; diff --git a/clang/test/CodeGenCXX/x86_64-arguments.cpp b/clang/test/CodeGenCXX/x86_64-arguments.cpp index d1bbf5d30f59e..ebeba7fd65495 100644 --- a/clang/test/CodeGenCXX/x86_64-arguments.cpp +++ b/clang/test/CodeGenCXX/x86_64-arguments.cpp @@ -173,7 +173,7 @@ namespace test9 { // CHECK: define{{.*}} void @_ZN5test93fooEPNS_1SEPNS_1TE(ptr %0, ptr %1) void foo(S*, T*) {} - // CHECK: define{{.*}} void @_ZN5test91aEiiiiNS_1TEPv(ptr noalias sret([[S:%.*]]) align 8 {{%.*}}, i32 %0, i32 %1, i32 %2, i32 %3, ptr byval([[T:%.*]]) align 8 %4, ptr %5) + // CHECK: define{{.*}} void @_ZN5test91aEiiiiNS_1TEPv(ptr dead_on_unwind noalias writable sret([[S:%.*]]) align 8 {{%.*}}, i32 %0, i32 %1, i32 %2, i32 %3, ptr byval([[T:%.*]]) align 8 %4, ptr %5) S a(int, int, int, int, T, void*) { return S(); } @@ -183,7 +183,7 @@ namespace test9 { return sret; } - // CHECK: define{{.*}} void @_ZN5test91cEiiiNS_1TEPv(ptr noalias sret([[S]]) align 8 {{%.*}}, i32 %0, i32 %1, i32 %2, ptr {{%.*}}, ptr {{%.*}}, ptr %3) + // CHECK: define{{.*}} void @_ZN5test91cEiiiNS_1TEPv(ptr dead_on_unwind noalias writable sret([[S]]) align 8 {{%.*}}, i32 %0, i32 %1, i32 %2, ptr {{%.*}}, ptr {{%.*}}, ptr %3) S c(int, int, int, T, void*) { return S(); } diff --git a/clang/test/CodeGenCoroutines/coro-await.cpp b/clang/test/CodeGenCoroutines/coro-await.cpp index e1c7039469afc..dc5a765ccb83d 100644 --- a/clang/test/CodeGenCoroutines/coro-await.cpp +++ b/clang/test/CodeGenCoroutines/coro-await.cpp @@ -127,7 +127,7 @@ extern "C" void f1(int) { // CHECK: %[[PROMISE:.+]] = alloca %"struct.std::coroutine_traits::promise_type" // CHECK: %[[FRAME:.+]] = call ptr @llvm.coro.begin( co_yield 42; - // CHECK: call void @_ZNSt16coroutine_traitsIJviEE12promise_type11yield_valueEi(ptr sret(%struct.suspend_maybe) align 4 %[[AWAITER:.+]], ptr {{[^,]*}} %[[PROMISE]], i32 42) + // CHECK: call void @_ZNSt16coroutine_traitsIJviEE12promise_type11yield_valueEi(ptr dead_on_unwind writable sret(%struct.suspend_maybe) align 4 %[[AWAITER:.+]], ptr {{[^,]*}} %[[PROMISE]], i32 42) // See if we need to suspend: // -------------------------- @@ -194,20 +194,20 @@ extern "C" void UseAggr(Aggr&&); extern "C" void TestAggr() { UseAggr(co_await AggrAwaiter{}); Whatever(); - // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(ptr sret(%struct.Aggr) align 4 %[[AwaitResume:.+]], + // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(ptr dead_on_unwind writable sret(%struct.Aggr) align 4 %[[AwaitResume:.+]], // CHECK: call void @UseAggr(ptr nonnull align 4 dereferenceable(12) %[[AwaitResume]]) // CHECK: call void @_ZN4AggrD1Ev(ptr {{[^,]*}} %[[AwaitResume]]) // CHECK: call void @Whatever() co_await AggrAwaiter{}; Whatever(); - // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(ptr sret(%struct.Aggr) align 4 %[[AwaitResume2:.+]], + // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(ptr dead_on_unwind writable sret(%struct.Aggr) align 4 %[[AwaitResume2:.+]], // CHECK: call void @_ZN4AggrD1Ev(ptr {{[^,]*}} %[[AwaitResume2]]) // CHECK: call void @Whatever() Aggr Val = co_await AggrAwaiter{}; Whatever(); - // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(ptr sret(%struct.Aggr) align 4 %[[AwaitResume3:.+]], + // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(ptr dead_on_unwind writable sret(%struct.Aggr) align 4 %[[AwaitResume3:.+]], // CHECK: call void @Whatever() // CHECK: call void @_ZN4AggrD1Ev(ptr {{[^,]*}} %[[AwaitResume3]]) } @@ -252,7 +252,7 @@ extern "C" void TestOpAwait() { co_await MyAgg{}; // CHECK: call void @_ZN5MyAggawEv(ptr {{[^,]*}} % - // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(ptr sret(%struct.Aggr) align 4 % + // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(ptr dead_on_unwind writable sret(%struct.Aggr) align 4 % } // CHECK-LABEL: EndlessLoop( diff --git a/clang/test/CodeGenCoroutines/coro-gro2.cpp b/clang/test/CodeGenCoroutines/coro-gro2.cpp index b0faa66edd333..56299574fbf25 100644 --- a/clang/test/CodeGenCoroutines/coro-gro2.cpp +++ b/clang/test/CodeGenCoroutines/coro-gro2.cpp @@ -34,13 +34,13 @@ struct coro { }; // Verify that the RVO is applied. -// CHECK-LABEL: define{{.*}} void @_Z1fi(ptr noalias sret(%struct.coro) align 8 %agg.result, i32 noundef %0) +// CHECK-LABEL: define{{.*}} void @_Z1fi(ptr dead_on_unwind noalias writable sret(%struct.coro) align 8 %agg.result, i32 noundef %0) coro f(int) { // CHECK: %call = call noalias noundef nonnull ptr @_Znwm( // CHECK-NEXT: br label %[[CoroInit:.*]] // CHECK: {{.*}}[[CoroInit]]: -// CHECK: call void @{{.*get_return_objectEv}}(ptr sret(%struct.coro) align 8 %agg.result +// CHECK: call void @{{.*get_return_objectEv}}(ptr dead_on_unwind writable sret(%struct.coro) align 8 %agg.result co_return; } @@ -63,7 +63,7 @@ struct coro_two { }; // Verify that the RVO is applied. -// CHECK-LABEL: define{{.*}} void @_Z1hi(ptr noalias sret(%struct.coro_two) align 8 %agg.result, i32 noundef %0) +// CHECK-LABEL: define{{.*}} void @_Z1hi(ptr dead_on_unwind noalias writable sret(%struct.coro_two) align 8 %agg.result, i32 noundef %0) coro_two h(int) { // CHECK: %call = call noalias noundef ptr @_ZnwmRKSt9nothrow_t @@ -71,11 +71,11 @@ coro_two h(int) { // CHECK-NEXT: br i1 %[[CheckNull]], label %[[InitOnSuccess:.*]], label %[[InitOnFailure:.*]] // CHECK: {{.*}}[[InitOnFailure]]: - // CHECK-NEXT: call void @{{.*get_return_object_on_allocation_failureEv}}(ptr sret(%struct.coro_two) align 8 %agg.result + // CHECK-NEXT: call void @{{.*get_return_object_on_allocation_failureEv}}(ptr dead_on_unwind writable sret(%struct.coro_two) align 8 %agg.result // CHECK-NEXT: br label %[[RetLabel:.*]] // CHECK: {{.*}}[[InitOnSuccess]]: - // CHECK: call void @{{.*get_return_objectEv}}(ptr sret(%struct.coro_two) align 8 %agg.result + // CHECK: call void @{{.*get_return_objectEv}}(ptr dead_on_unwind writable sret(%struct.coro_two) align 8 %agg.result // CHECK: [[RetLabel]]: // CHECK-NEXT: ret void diff --git a/clang/test/CodeGenHLSL/sret_output.hlsl b/clang/test/CodeGenHLSL/sret_output.hlsl index 6b15e017a024d..33f88c639525f 100644 --- a/clang/test/CodeGenHLSL/sret_output.hlsl +++ b/clang/test/CodeGenHLSL/sret_output.hlsl @@ -10,7 +10,7 @@ struct S { // Make sure sret parameter is generated. -// CHECK:define internal void @"?ps_main@@YA?AUS@@XZ"(ptr noalias sret(%struct.S) align 4 %agg.result) +// CHECK:define internal void @"?ps_main@@YA?AUS@@XZ"(ptr dead_on_unwind noalias writable sret(%struct.S) align 4 %agg.result) // FIXME: change it to real value instead of poison value once semantic is add to a. // Make sure the function with sret is called. // CHECK:call void @"?ps_main@@YA?AUS@@XZ"(ptr poison) diff --git a/clang/test/CodeGenObjC/arc.m b/clang/test/CodeGenObjC/arc.m index 74356d8895d14..aeead58f8131d 100644 --- a/clang/test/CodeGenObjC/arc.m +++ b/clang/test/CodeGenObjC/arc.m @@ -1358,11 +1358,11 @@ void test70(id i) { // CHECK-LABEL: define{{.*}} void @test71 void test71(void) { // CHECK: call void @llvm.lifetime.start.p0({{[^,]+}}, ptr %[[T:.*]]) - // CHECK: call void @getAggDtor(ptr sret(%struct.AggDtor) align 8 %[[T]]) + // CHECK: call void @getAggDtor(ptr dead_on_unwind writable sret(%struct.AggDtor) align 8 %[[T]]) // CHECK: call void @__destructor_8_s40(ptr %[[T]]) // CHECK: call void @llvm.lifetime.end.p0({{[^,]+}}, ptr %[[T]]) // CHECK: call void @llvm.lifetime.start.p0({{[^,]+}}, ptr %[[T2:.*]]) - // CHECK: call void @getAggDtor(ptr sret(%struct.AggDtor) align 8 %[[T2]]) + // CHECK: call void @getAggDtor(ptr dead_on_unwind writable sret(%struct.AggDtor) align 8 %[[T2]]) // CHECK: call void @__destructor_8_s40(ptr %[[T2]]) // CHECK: call void @llvm.lifetime.end.p0({{[^,]+}}, ptr %[[T2]]) getAggDtor(); diff --git a/clang/test/CodeGenObjC/direct-method.m b/clang/test/CodeGenObjC/direct-method.m index 8a3c2f575d2d3..028a0888d594e 100644 --- a/clang/test/CodeGenObjC/direct-method.m +++ b/clang/test/CodeGenObjC/direct-method.m @@ -111,7 +111,7 @@ + (struct my_complex_struct)classGetComplex __attribute__((objc_direct)) { // CHECK-LABEL: define hidden void @"\01-[Root getAggregate]"( - (struct my_aggregate_struct)getAggregate __attribute__((objc_direct)) { - // CHECK: ptr noalias sret(%struct.my_aggregate_struct) align 4 [[RETVAL:%[^,]*]], + // CHECK: ptr dead_on_unwind noalias writable sret(%struct.my_aggregate_struct) align 4 [[RETVAL:%[^,]*]], // loading parameters // CHECK-LABEL: entry: diff --git a/clang/test/CodeGenObjC/nontrivial-c-struct-exception.m b/clang/test/CodeGenObjC/nontrivial-c-struct-exception.m index 0159e111d9ad0..d2a954ae26a04 100644 --- a/clang/test/CodeGenObjC/nontrivial-c-struct-exception.m +++ b/clang/test/CodeGenObjC/nontrivial-c-struct-exception.m @@ -39,8 +39,8 @@ void testStrongException(void) { // CHECK: define{{.*}} void @testWeakException() // CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_WEAK]], align 8 // CHECK: %[[AGG_TMP1:.*]] = alloca %[[STRUCT_WEAK]], align 8 -// CHECK: call void @genWeak(ptr sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP]]) -// CHECK: invoke void @genWeak(ptr sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP1]]) +// CHECK: call void @genWeak(ptr dead_on_unwind writable sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP]]) +// CHECK: invoke void @genWeak(ptr dead_on_unwind writable sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_TMP1]]) // CHECK: call void @calleeWeak(ptr noundef %[[AGG_TMP]], ptr noundef %[[AGG_TMP1]]) // CHECK: ret void diff --git a/clang/test/CodeGenObjC/objc-non-trivial-struct-nrvo.m b/clang/test/CodeGenObjC/objc-non-trivial-struct-nrvo.m index effba8c958441..cc697b0e15373 100644 --- a/clang/test/CodeGenObjC/objc-non-trivial-struct-nrvo.m +++ b/clang/test/CodeGenObjC/objc-non-trivial-struct-nrvo.m @@ -37,7 +37,7 @@ Trivial testTrivial(void) { void func1(TrivialBig *); -// CHECK: define{{.*}} void @testTrivialBig(ptr noalias sret(%[[STRUCT_TRIVIALBIG]]) align 4 %[[AGG_RESULT:.*]]) +// CHECK: define{{.*}} void @testTrivialBig(ptr dead_on_unwind noalias writable sret(%[[STRUCT_TRIVIALBIG]]) align 4 %[[AGG_RESULT:.*]]) // CHECK: call void @func1(ptr noundef %[[AGG_RESULT]]) // CHECK-NEXT: ret void @@ -67,7 +67,7 @@ Strong testStrong(void) { return a; } -// CHECK: define{{.*}} void @testWeak(ptr noalias sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_RESULT:.*]]) +// CHECK: define{{.*}} void @testWeak(ptr dead_on_unwind noalias writable sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_RESULT:.*]]) // CHECK: %[[NRVO:.*]] = alloca i1, align 1 // CHECK: call void @__default_constructor_8_w0(ptr %[[AGG_RESULT]]) // CHECK: store i1 true, ptr %[[NRVO]], align 1 @@ -101,7 +101,7 @@ Weak testWeak2(int c) { return b; } -// CHECK: define internal void @"\01-[C1 foo1]"(ptr noalias sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_RESULT:.*]], ptr noundef %{{.*}}, ptr noundef %{{.*}}) +// CHECK: define internal void @"\01-[C1 foo1]"(ptr dead_on_unwind noalias writable sret(%[[STRUCT_WEAK]]) align 8 %[[AGG_RESULT:.*]], ptr noundef %{{.*}}, ptr noundef %{{.*}}) // CHECK: %[[NRVO:.*]] = alloca i1, align 1 // CHECK: call void @__default_constructor_8_w0(ptr %[[AGG_RESULT]]) // CHECK: store i1 true, ptr %[[NRVO]], align 1 diff --git a/clang/test/CodeGenObjC/stret-1.m b/clang/test/CodeGenObjC/stret-1.m index fb1b4abe70f4c..20e26af72c6f9 100644 --- a/clang/test/CodeGenObjC/stret-1.m +++ b/clang/test/CodeGenObjC/stret-1.m @@ -13,18 +13,18 @@ int main(int argc, const char **argv) { struct stret s; s = [(id)(argc&~255) method]; - // CHECK: call void @objc_msgSend(ptr sret(%struct.stret) align 4 [[T0:%[^,]+]] + // CHECK: call void @objc_msgSend(ptr dead_on_unwind writable sret(%struct.stret) align 4 [[T0:%[^,]+]] // CHECK: call void @llvm.memset.p0.i64(ptr align 4 [[T0]], i8 0, i64 400, i1 false) s = [Test method]; - // CHECK: call void @objc_msgSend(ptr sret(%struct.stret) align 4 [[T1:%[^,]+]] + // CHECK: call void @objc_msgSend(ptr dead_on_unwind writable sret(%struct.stret) align 4 [[T1:%[^,]+]] // CHECK-NOT: call void @llvm.memset.p0.i64( [(id)(argc&~255) method]; - // CHECK: call void @objc_msgSend(ptr sret(%struct.stret) align 4 [[T1:%[^,]+]] + // CHECK: call void @objc_msgSend(ptr dead_on_unwind writable sret(%struct.stret) align 4 [[T1:%[^,]+]] // CHECK-NOT: call void @llvm.memset.p0.i64( [Test method]; - // CHECK: call void @objc_msgSend(ptr sret(%struct.stret) align 4 [[T1:%[^,]+]] + // CHECK: call void @objc_msgSend(ptr dead_on_unwind writable sret(%struct.stret) align 4 [[T1:%[^,]+]] // CHECK-NOT: call void @llvm.memset.p0.i64( } diff --git a/clang/test/CodeGenObjC/stret_lookup.m b/clang/test/CodeGenObjC/stret_lookup.m index 1a4665d4309db..315a1627da5b7 100644 --- a/clang/test/CodeGenObjC/stret_lookup.m +++ b/clang/test/CodeGenObjC/stret_lookup.m @@ -20,8 +20,8 @@ void test0(void) { // HASSTRET-LABEL: define{{.*}} void @test0() // HASSTRET: [[T0:%.*]] = call ptr @objc_msg_lookup_stret(ptr @_OBJC_CLASS_Test0, -// HASSTRET-NEXT: call void [[T0]](ptr sret(%struct.test) {{.*}}, ptr noundef @_OBJC_CLASS_Test0, +// HASSTRET-NEXT: call void [[T0]](ptr dead_on_unwind writable sret(%struct.test) {{.*}}, ptr noundef @_OBJC_CLASS_Test0, // NOSTRET-LABEL: define{{.*}} void @test0() // NOSTRET: [[T0:%.*]] = call ptr @objc_msg_lookup(ptr -// NOSTRET-NEXT: call void [[T0]](ptr sret(%struct.test) {{.*}}, ptr {{.*}}, ptr noundef +// NOSTRET-NEXT: call void [[T0]](ptr dead_on_unwind writable sret(%struct.test) {{.*}}, ptr {{.*}}, ptr noundef diff --git a/clang/test/CodeGenObjC/weak-in-c-struct.m b/clang/test/CodeGenObjC/weak-in-c-struct.m index 3ec08c2b9f18b..be80edd1ff11d 100644 --- a/clang/test/CodeGenObjC/weak-in-c-struct.m +++ b/clang/test/CodeGenObjC/weak-in-c-struct.m @@ -149,7 +149,7 @@ void test_argument_Weak(Weak *a) { calleeWeak(*a); } -// COMMON: define{{.*}} void @test_return_Weak(ptr noalias sret(%[[STRUCT_WEAK]]) align {{.*}} %[[AGG_RESULT:.*]], ptr noundef %[[A:.*]]) +// COMMON: define{{.*}} void @test_return_Weak(ptr dead_on_unwind noalias writable sret(%[[STRUCT_WEAK]]) align {{.*}} %[[AGG_RESULT:.*]], ptr noundef %[[A:.*]]) // COMMON: %[[A_ADDR:.*]] = alloca ptr // COMMON: store ptr %[[A]], ptr %[[A_ADDR]] // COMMON: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]] diff --git a/clang/test/CodeGenObjC/x86_64-struct-return-gc.m b/clang/test/CodeGenObjC/x86_64-struct-return-gc.m index 6bc2929c7596f..bc0b88ff037ff 100644 --- a/clang/test/CodeGenObjC/x86_64-struct-return-gc.m +++ b/clang/test/CodeGenObjC/x86_64-struct-return-gc.m @@ -25,7 +25,7 @@ void Coerce_test(void) { void Indirect_test(void) { struct Indirect i; - // CHECK: call void @indirect_func(ptr sret + // CHECK: call void @indirect_func(ptr dead_on_unwind writable sret // CHECK: call ptr @objc_memmove_collectable( i = indirect_func(); } diff --git a/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm b/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm index ed35eb1a7983a..f9f783ff5caca 100644 --- a/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm +++ b/clang/test/CodeGenObjCXX/objc-struct-cxx-abi.mm @@ -96,7 +96,7 @@ void testCallStrongWeak(StrongWeak *a) { testParamStrongWeak(*a); } -// CHECK: define{{.*}} void @_Z20testReturnStrongWeakP10StrongWeak(ptr noalias sret(%[[STRUCT_STRONGWEAK:.*]]) align 8 %[[AGG_RESULT:.*]], ptr noundef %[[A:.*]]) +// CHECK: define{{.*}} void @_Z20testReturnStrongWeakP10StrongWeak(ptr dead_on_unwind noalias writable sret(%[[STRUCT_STRONGWEAK:.*]]) align 8 %[[AGG_RESULT:.*]], ptr noundef %[[A:.*]]) // CHECK: %[[A_ADDR:a.addr]] = alloca ptr, align 8 // CHECK: store ptr %[[A]], ptr %[[A_ADDR]], align 8 // CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8 diff --git a/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl b/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl index 054fdc0662228..385f8a753cd8e 100644 --- a/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl +++ b/clang/test/CodeGenOpenCL/addr-space-struct-arg.cl @@ -45,7 +45,7 @@ struct LargeStructTwoMember { struct LargeStructOneMember g_s; #endif -// X86-LABEL: define{{.*}} void @foo(ptr noalias sret(%struct.Mat4X4) align 4 %agg.result, ptr noundef byval(%struct.Mat3X3) align 4 %in) +// X86-LABEL: define{{.*}} void @foo(ptr dead_on_unwind noalias writable sret(%struct.Mat4X4) align 4 %agg.result, ptr noundef byval(%struct.Mat3X3) align 4 %in) // AMDGCN-LABEL: define{{.*}} %struct.Mat4X4 @foo([9 x i32] %in.coerce) Mat4X4 __attribute__((noinline)) foo(Mat3X3 in) { Mat4X4 out; @@ -65,8 +65,8 @@ kernel void ker(global Mat3X3 *in, global Mat4X4 *out) { out[0] = foo(in[1]); } -// X86-LABEL: define{{.*}} void @foo_large(ptr noalias sret(%struct.Mat64X64) align 4 %agg.result, ptr noundef byval(%struct.Mat32X32) align 4 %in) -// AMDGCN-LABEL: define{{.*}} void @foo_large(ptr addrspace(5) noalias sret(%struct.Mat64X64) align 4 %agg.result, ptr addrspace(5) noundef byref(%struct.Mat32X32) align 4 %{{.*}} +// X86-LABEL: define{{.*}} void @foo_large(ptr dead_on_unwind noalias writable sret(%struct.Mat64X64) align 4 %agg.result, ptr noundef byval(%struct.Mat32X32) align 4 %in) +// AMDGCN-LABEL: define{{.*}} void @foo_large(ptr addrspace(5) dead_on_unwind noalias writable sret(%struct.Mat64X64) align 4 %agg.result, ptr addrspace(5) noundef byref(%struct.Mat32X32) align 4 %{{.*}} // AMDGCN: %in = alloca %struct.Mat32X32, align 4, addrspace(5) // AMDGCN-NEXT: call void @llvm.memcpy.p5.p5.i64(ptr addrspace(5) align 4 %in, ptr addrspace(5) align 4 %{{.*}}, i64 4096, i1 false) Mat64X64 __attribute__((noinline)) foo_large(Mat32X32 in) { diff --git a/clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl b/clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl index 52fad9599de04..fa83a38a01b0a 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-abi-struct-arg-byref.cl @@ -86,7 +86,7 @@ kernel void ker(global Mat3X3 *in, global Mat4X4 *out) { } // AMDGCN-LABEL: define dso_local void @foo_large -// AMDGCN-SAME: (ptr addrspace(5) noalias sret([[STRUCT_MAT64X64:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr addrspace(5) noundef byref([[STRUCT_MAT32X32:%.*]]) align 4 [[TMP0:%.*]]) #[[ATTR0]] { +// AMDGCN-SAME: (ptr addrspace(5) dead_on_unwind noalias writable sret([[STRUCT_MAT64X64:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr addrspace(5) noundef byref([[STRUCT_MAT32X32:%.*]]) align 4 [[TMP0:%.*]]) #[[ATTR0]] { // AMDGCN-NEXT: entry: // AMDGCN-NEXT: [[IN:%.*]] = alloca [[STRUCT_MAT32X32]], align 4, addrspace(5) // AMDGCN-NEXT: call void @llvm.memcpy.p5.p5.i64(ptr addrspace(5) align 4 [[IN]], ptr addrspace(5) align 4 [[TMP0]], i64 4096, i1 false) @@ -111,7 +111,7 @@ Mat64X64 __attribute__((noinline)) foo_large(Mat32X32 in) { // AMDGCN-NEXT: [[TMP1:%.*]] = load ptr addrspace(1), ptr addrspace(5) [[IN_ADDR]], align 8 // AMDGCN-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [[STRUCT_MAT32X32]], ptr addrspace(1) [[TMP1]], i64 1 // AMDGCN-NEXT: call void @llvm.memcpy.p5.p1.i64(ptr addrspace(5) align 4 [[BYVAL_TEMP]], ptr addrspace(1) align 4 [[ARRAYIDX1]], i64 4096, i1 false) -// AMDGCN-NEXT: call void @foo_large(ptr addrspace(5) sret([[STRUCT_MAT64X64]]) align 4 [[TMP]], ptr addrspace(5) noundef byref([[STRUCT_MAT32X32]]) align 4 [[BYVAL_TEMP]]) #[[ATTR3]] +// AMDGCN-NEXT: call void @foo_large(ptr addrspace(5) dead_on_unwind writable sret([[STRUCT_MAT64X64]]) align 4 [[TMP]], ptr addrspace(5) noundef byref([[STRUCT_MAT32X32]]) align 4 [[BYVAL_TEMP]]) #[[ATTR3]] // AMDGCN-NEXT: call void @llvm.memcpy.p1.p5.i64(ptr addrspace(1) align 4 [[ARRAYIDX]], ptr addrspace(5) align 4 [[TMP]], i64 16384, i1 false) // AMDGCN-NEXT: ret void // diff --git a/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl b/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl index 665609e54a83e..90e4b65c6f1f7 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl @@ -402,14 +402,14 @@ struct_arr16 func_ret_struct_arr16() return s; } -// CHECK: define{{.*}} void @func_ret_struct_arr32(ptr addrspace(5) noalias nocapture writeonly sret(%struct.struct_arr32) align 4 %agg.result) +// CHECK: define{{.*}} void @func_ret_struct_arr32(ptr addrspace(5) dead_on_unwind noalias nocapture writable writeonly sret(%struct.struct_arr32) align 4 %agg.result) struct_arr32 func_ret_struct_arr32() { struct_arr32 s = { 0 }; return s; } -// CHECK: define{{.*}} void @func_ret_struct_arr33(ptr addrspace(5) noalias nocapture writeonly sret(%struct.struct_arr33) align 4 %agg.result) +// CHECK: define{{.*}} void @func_ret_struct_arr33(ptr addrspace(5) dead_on_unwind noalias nocapture writable writeonly sret(%struct.struct_arr33) align 4 %agg.result) struct_arr33 func_ret_struct_arr33() { struct_arr33 s = { 0 }; @@ -438,7 +438,7 @@ different_size_type_pair func_different_size_type_pair_ret() return s; } -// CHECK: define{{.*}} void @func_flexible_array_ret(ptr addrspace(5) noalias nocapture writeonly sret(%struct.flexible_array) align 4 %agg.result) +// CHECK: define{{.*}} void @func_flexible_array_ret(ptr addrspace(5) dead_on_unwind noalias nocapture writable writeonly sret(%struct.flexible_array) align 4 %agg.result) flexible_array func_flexible_array_ret() { flexible_array s = { 0 }; diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-of-this.clcpp b/clang/test/CodeGenOpenCLCXX/addrspace-of-this.clcpp index 1c09743d3c8db..2f1b6c196fd51 100644 --- a/clang/test/CodeGenOpenCLCXX/addrspace-of-this.clcpp +++ b/clang/test/CodeGenOpenCLCXX/addrspace-of-this.clcpp @@ -111,7 +111,7 @@ __kernel void test__global() { // Test the address space of 'this' when invoking the operator+ // COMMON: [[C1GEN:%[.a-z0-9]+]] = addrspacecast ptr %c1 to ptr addrspace(4) // COMMON: [[C2GEN:%[.a-z0-9]+]] = addrspacecast ptr %c2 to ptr addrspace(4) -// COMMON: call spir_func void @_ZNU3AS41CplERU3AS4KS_(ptr sret(%class.C) align 4 %c3, ptr addrspace(4) {{[^,]*}} [[C1GEN]], ptr addrspace(4) noundef align 4 dereferenceable(4) [[C2GEN]]) +// COMMON: call spir_func void @_ZNU3AS41CplERU3AS4KS_(ptr dead_on_unwind writable sret(%class.C) align 4 %c3, ptr addrspace(4) {{[^,]*}} [[C1GEN]], ptr addrspace(4) noundef align 4 dereferenceable(4) [[C2GEN]]) // Test the address space of 'this' when invoking the move constructor // COMMON: [[C4GEN:%[.a-z0-9]+]] = addrspacecast ptr %c4 to ptr addrspace(4) @@ -127,7 +127,7 @@ __kernel void test__global() { // Tests address space of inline members //COMMON: @_ZNU3AS41C3getEv(ptr addrspace(4) {{[^,]*}} %this) -//COMMON: @_ZNU3AS41CplERU3AS4KS_(ptr noalias sret(%class.C) align 4 %agg.result, ptr addrspace(4) {{[^,]*}} %this +//COMMON: @_ZNU3AS41CplERU3AS4KS_(ptr dead_on_unwind noalias writable sret(%class.C) align 4 %agg.result, ptr addrspace(4) {{[^,]*}} %this #define TEST(AS) \ __kernel void test##AS() { \ AS C c; \ diff --git a/clang/test/Modules/templates.mm b/clang/test/Modules/templates.mm index 0e66c9843cc09..d7b7d5af030a7 100644 --- a/clang/test/Modules/templates.mm +++ b/clang/test/Modules/templates.mm @@ -125,7 +125,7 @@ void testWithAttributes() { // Check that returnNonTrivial doesn't return Class0 directly in registers. -// CHECK: declare void @_Z16returnNonTrivialv(ptr sret(%struct.Class0) align 8) +// CHECK: declare void @_Z16returnNonTrivialv(ptr dead_on_unwind writable sret(%struct.Class0) align 8) @import template_nontrivial0; @import template_nontrivial1; diff --git a/clang/test/OpenMP/irbuilder_for_iterator.cpp b/clang/test/OpenMP/irbuilder_for_iterator.cpp index 91bbb6fc18ddb..b88416b36c4fa 100644 --- a/clang/test/OpenMP/irbuilder_for_iterator.cpp +++ b/clang/test/OpenMP/irbuilder_for_iterator.cpp @@ -159,7 +159,7 @@ extern "C" void workshareloop_iterator(float *a, float *b, float *c) { // CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[LOGICAL_ADDR]], align 8 // CHECK-NEXT: [[MUL:%.*]] = mul i64 1, [[TMP2]] // CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[MUL]] to i32 -// CHECK-NEXT: call void @_ZNK10MyIteratorplEj(ptr sret([[STRUCT_MYITERATOR]]) align 1 [[REF_TMP]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]], i32 noundef [[CONV]]) +// CHECK-NEXT: call void @_ZNK10MyIteratorplEj(ptr dead_on_unwind writable sret([[STRUCT_MYITERATOR]]) align 1 [[REF_TMP]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]], i32 noundef [[CONV]]) // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[LOOPVAR_ADDR]], align 8 // CHECK-NEXT: [[CALL:%.*]] = call noundef nonnull align 1 dereferenceable(1) ptr @_ZN10MyIteratoraSERKS_(ptr noundef nonnull align 1 dereferenceable(1) [[TMP3]], ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) // CHECK-NEXT: ret void diff --git a/clang/test/OpenMP/irbuilder_for_rangefor.cpp b/clang/test/OpenMP/irbuilder_for_rangefor.cpp index 3b952d43eb257..6bf91bfda138a 100644 --- a/clang/test/OpenMP/irbuilder_for_rangefor.cpp +++ b/clang/test/OpenMP/irbuilder_for_rangefor.cpp @@ -57,9 +57,9 @@ extern "C" void workshareloop_rangefor(float *a, float *b, float *c) { // CHECK-NEXT: call void @_ZN7MyRangeC1Ei(ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]], i32 noundef 42) // CHECK-NEXT: store ptr [[REF_TMP]], ptr [[__RANGE2]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[__RANGE2]], align 8 -// CHECK-NEXT: call void @_ZN7MyRange5beginEv(ptr sret([[STRUCT_MYITERATOR]]) align 1 [[__BEGIN2]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP0]]) +// CHECK-NEXT: call void @_ZN7MyRange5beginEv(ptr dead_on_unwind writable sret([[STRUCT_MYITERATOR]]) align 1 [[__BEGIN2]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP0]]) // CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[__RANGE2]], align 8 -// CHECK-NEXT: call void @_ZN7MyRange3endEv(ptr sret([[STRUCT_MYITERATOR]]) align 1 [[__END2]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]]) +// CHECK-NEXT: call void @_ZN7MyRange3endEv(ptr dead_on_unwind writable sret([[STRUCT_MYITERATOR]]) align 1 [[__END2]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]]) // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZNK10MyIteratordeEv(ptr noundef nonnull align 1 dereferenceable(1) [[__BEGIN2]]) // CHECK-NEXT: store i32 [[CALL]], ptr [[I]], align 4 // CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_ANON]], ptr [[AGG_CAPTURED]], i32 0, i32 0 @@ -177,7 +177,7 @@ extern "C" void workshareloop_rangefor(float *a, float *b, float *c) { // CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[LOGICAL_ADDR]], align 8 // CHECK-NEXT: [[MUL:%.*]] = mul i64 1, [[TMP2]] // CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[MUL]] to i32 -// CHECK-NEXT: call void @_ZNK10MyIteratorplEj(ptr sret([[STRUCT_MYITERATOR]]) align 1 [[REF_TMP]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]], i32 noundef [[CONV]]) +// CHECK-NEXT: call void @_ZNK10MyIteratorplEj(ptr dead_on_unwind writable sret([[STRUCT_MYITERATOR]]) align 1 [[REF_TMP]], ptr noundef nonnull align 1 dereferenceable(1) [[TMP1]], i32 noundef [[CONV]]) // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZNK10MyIteratordeEv(ptr noundef nonnull align 1 dereferenceable(1) [[REF_TMP]]) // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[LOOPVAR_ADDR]], align 8 // CHECK-NEXT: store i32 [[CALL]], ptr [[TMP3]], align 4 diff --git a/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp b/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp index 7afaf035988f0..41c086c7e1d06 100644 --- a/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_in_reduction_codegen.cpp @@ -339,7 +339,7 @@ int main(int argc, char **argv) { // CHECK1: omp.arraycpy.body: // CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[TMP3]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[TMP2]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] -// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) +// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr dead_on_unwind writable sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) // CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @_ZN1SaSERKS_(ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) // CHECK1-NEXT: call void @_ZN1SD1Ev(ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) #[[ATTR3]] // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1 @@ -351,7 +351,7 @@ int main(int argc, char **argv) { // // // CHECK1-LABEL: define {{[^@]+}}@_ZplRK1SS1_ -// CHECK1-SAME: (ptr noalias sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { +// CHECK1-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 diff --git a/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp b/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp index 5d6404cd3e54b..f25fe346c835e 100644 --- a/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/master_taskloop_simd_in_reduction_codegen.cpp @@ -339,7 +339,7 @@ int main(int argc, char **argv) { // CHECK1: omp.arraycpy.body: // CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[TMP3]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[TMP2]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] -// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) +// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr dead_on_unwind writable sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) // CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @_ZN1SaSERKS_(ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) // CHECK1-NEXT: call void @_ZN1SD1Ev(ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) #[[ATTR3]] // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1 @@ -351,7 +351,7 @@ int main(int argc, char **argv) { // // // CHECK1-LABEL: define {{[^@]+}}@_ZplRK1SS1_ -// CHECK1-SAME: (ptr noalias sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { +// CHECK1-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 diff --git a/clang/test/OpenMP/target_in_reduction_codegen.cpp b/clang/test/OpenMP/target_in_reduction_codegen.cpp index 2eb6058461244..c6b8afba52ee5 100644 --- a/clang/test/OpenMP/target_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/target_in_reduction_codegen.cpp @@ -333,7 +333,7 @@ int main(int argc, char **argv) { // CHECK1: omp.arraycpy.body: // CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[TMP5]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[TMP3]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] -// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) +// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr dead_on_unwind writable sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) // CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @_ZN1SaSERKS_(ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) // CHECK1-NEXT: call void @_ZN1SD1Ev(ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) #3 // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1 @@ -345,7 +345,7 @@ int main(int argc, char **argv) { // // // CHECK1-LABEL: define {{[^@]+}}@_ZplRK1SS1_ -// CHECK1-SAME: (ptr noalias sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR7:[0-9]+]] { +// CHECK1-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR7:[0-9]+]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 diff --git a/clang/test/OpenMP/task_in_reduction_codegen.cpp b/clang/test/OpenMP/task_in_reduction_codegen.cpp index 82d2038943646..348bd7bea3b4a 100644 --- a/clang/test/OpenMP/task_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/task_in_reduction_codegen.cpp @@ -361,7 +361,7 @@ int main(int argc, char **argv) { // CHECK1: omp.arraycpy.body: // CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[TMP3]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[TMP2]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] -// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) +// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr dead_on_unwind writable sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) // CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @_ZN1SaSERKS_(ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) // CHECK1-NEXT: call void @_ZN1SD1Ev(ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) #[[ATTR3]] // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1 @@ -373,7 +373,7 @@ int main(int argc, char **argv) { // // // CHECK1-LABEL: define {{[^@]+}}@_ZplRK1SS1_ -// CHECK1-SAME: (ptr noalias sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { +// CHECK1-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 diff --git a/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp b/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp index e48035a71eea9..abf9164b789d3 100644 --- a/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/taskloop_in_reduction_codegen.cpp @@ -339,7 +339,7 @@ int main(int argc, char **argv) { // CHECK1: omp.arraycpy.body: // CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[TMP3]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[TMP2]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] -// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) +// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr dead_on_unwind writable sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) // CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @_ZN1SaSERKS_(ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) // CHECK1-NEXT: call void @_ZN1SD1Ev(ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) #[[ATTR3]] // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1 @@ -351,7 +351,7 @@ int main(int argc, char **argv) { // // // CHECK1-LABEL: define {{[^@]+}}@_ZplRK1SS1_ -// CHECK1-SAME: (ptr noalias sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { +// CHECK1-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 diff --git a/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp b/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp index e4d24fa482440..f279596401a8e 100644 --- a/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp +++ b/clang/test/OpenMP/taskloop_simd_in_reduction_codegen.cpp @@ -339,7 +339,7 @@ int main(int argc, char **argv) { // CHECK1: omp.arraycpy.body: // CHECK1-NEXT: [[OMP_ARRAYCPY_SRCELEMENTPAST:%.*]] = phi ptr [ [[TMP3]], [[ENTRY:%.*]] ], [ [[OMP_ARRAYCPY_SRC_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] // CHECK1-NEXT: [[OMP_ARRAYCPY_DESTELEMENTPAST:%.*]] = phi ptr [ [[TMP2]], [[ENTRY]] ], [ [[OMP_ARRAYCPY_DEST_ELEMENT:%.*]], [[OMP_ARRAYCPY_BODY]] ] -// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) +// CHECK1-NEXT: call void @_ZplRK1SS1_(ptr dead_on_unwind writable sret([[STRUCT_S]]) align 4 [[REF_TMP]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_SRCELEMENTPAST]]) // CHECK1-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @_ZN1SaSERKS_(ptr nonnull align 4 dereferenceable(4) [[OMP_ARRAYCPY_DESTELEMENTPAST]], ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) // CHECK1-NEXT: call void @_ZN1SD1Ev(ptr nonnull align 4 dereferenceable(4) [[REF_TMP]]) #[[ATTR3]] // CHECK1-NEXT: [[OMP_ARRAYCPY_DEST_ELEMENT]] = getelementptr [[STRUCT_S]], ptr [[OMP_ARRAYCPY_DESTELEMENTPAST]], i32 1 @@ -351,7 +351,7 @@ int main(int argc, char **argv) { // // // CHECK1-LABEL: define {{[^@]+}}@_ZplRK1SS1_ -// CHECK1-SAME: (ptr noalias sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { +// CHECK1-SAME: (ptr dead_on_unwind noalias writable sret([[STRUCT_S:%.*]]) align 4 [[AGG_RESULT:%.*]], ptr nonnull align 4 dereferenceable(4) [[A:%.*]], ptr nonnull align 4 dereferenceable(4) [[B:%.*]]) #[[ATTR1]] { // CHECK1-NEXT: entry: // CHECK1-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 8 // CHECK1-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 From d7642b2200bdd7dc12f5fe1a840e1fd43b1bbd73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Sch=C3=BCtt?= Date: Thu, 11 Jan 2024 09:50:33 +0100 Subject: [PATCH 012/841] [GlobalIsel] Combine select to integer minmax (second attempt). (#77520) Instcombine canonicalizes selects to floating point and integer minmax. This and the dag combiner canonicalize to floating point minmax. None of them canonicalizes to integer minmax. On Neoverse V2 basic integer arithmetic and integer minmax have the same costs. --- .../llvm/CodeGen/GlobalISel/CombinerHelper.h | 3 + .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 84 ++++++ .../AArch64/GlobalISel/arm64-atomic.ll | 32 +- .../AArch64/GlobalISel/arm64-pcsections.ll | 8 +- .../AArch64/GlobalISel/combine-select.mir | 281 ++++++++++++++++++ 5 files changed, 388 insertions(+), 20 deletions(-) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h index dcc1a4580b14a..a6e9406bed06a 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h @@ -910,6 +910,9 @@ class CombinerHelper { bool tryFoldSelectOfConstants(GSelect *Select, BuildFnTy &MatchInfo); + /// Try to fold (icmp X, Y) ? X : Y -> integer minmax. + bool tryFoldSelectToIntMinMax(GSelect *Select, BuildFnTy &MatchInfo); + bool isOneOrOneSplat(Register Src, bool AllowUndefs); bool isZeroOrZeroSplat(Register Src, bool AllowUndefs); bool isConstantSplatVector(Register Src, int64_t SplatValue, diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 8b15bdb0aca30..fc2793bd7a133 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -6548,6 +6548,87 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select, return false; } +bool CombinerHelper::tryFoldSelectToIntMinMax(GSelect *Select, + BuildFnTy &MatchInfo) { + Register DstReg = Select->getReg(0); + Register Cond = Select->getCondReg(); + Register True = Select->getTrueReg(); + Register False = Select->getFalseReg(); + LLT DstTy = MRI.getType(DstReg); + + // We need an G_ICMP on the condition register. + GICmp *Cmp = getOpcodeDef(Cond, MRI); + if (!Cmp) + return false; + + // We want to fold the icmp and replace the select. + if (!MRI.hasOneNonDBGUse(Cmp->getReg(0))) + return false; + + CmpInst::Predicate Pred = Cmp->getCond(); + // We need a larger or smaller predicate for + // canonicalization. + if (CmpInst::isEquality(Pred)) + return false; + + Register CmpLHS = Cmp->getLHSReg(); + Register CmpRHS = Cmp->getRHSReg(); + + // We can swap CmpLHS and CmpRHS for higher hitrate. + if (True == CmpRHS && False == CmpLHS) { + std::swap(CmpLHS, CmpRHS); + Pred = CmpInst::getSwappedPredicate(Pred); + } + + // (icmp X, Y) ? X : Y -> integer minmax. + // see matchSelectPattern in ValueTracking. + // Legality between G_SELECT and integer minmax can differ. + if (True == CmpLHS && False == CmpRHS) { + switch (Pred) { + case ICmpInst::ICMP_UGT: + case ICmpInst::ICMP_UGE: { + if (!isLegalOrBeforeLegalizer({TargetOpcode::G_UMAX, DstTy})) + return false; + MatchInfo = [=](MachineIRBuilder &B) { + B.buildUMax(DstReg, True, False); + }; + return true; + } + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_SGE: { + if (!isLegalOrBeforeLegalizer({TargetOpcode::G_SMAX, DstTy})) + return false; + MatchInfo = [=](MachineIRBuilder &B) { + B.buildSMax(DstReg, True, False); + }; + return true; + } + case ICmpInst::ICMP_ULT: + case ICmpInst::ICMP_ULE: { + if (!isLegalOrBeforeLegalizer({TargetOpcode::G_UMIN, DstTy})) + return false; + MatchInfo = [=](MachineIRBuilder &B) { + B.buildUMin(DstReg, True, False); + }; + return true; + } + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_SLE: { + if (!isLegalOrBeforeLegalizer({TargetOpcode::G_SMIN, DstTy})) + return false; + MatchInfo = [=](MachineIRBuilder &B) { + B.buildSMin(DstReg, True, False); + }; + return true; + } + default: + return false; + } + } + + return false; +} + bool CombinerHelper::matchSelect(MachineInstr &MI, BuildFnTy &MatchInfo) { GSelect *Select = cast(&MI); @@ -6557,5 +6638,8 @@ bool CombinerHelper::matchSelect(MachineInstr &MI, BuildFnTy &MatchInfo) { if (tryFoldBoolSelectToLogic(Select, MatchInfo)) return true; + if (tryFoldSelectToIntMinMax(Select, MatchInfo)) + return true; + return false; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic.ll index 739332414c198..0e9c126e97a3d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic.ll @@ -2421,7 +2421,7 @@ define i8 @atomicrmw_min_i8(ptr %ptr, i8 %rhs) { ; CHECK-NOLSE-O1-NEXT: ldaxrb w8, [x0] ; CHECK-NOLSE-O1-NEXT: sxtb w9, w8 ; CHECK-NOLSE-O1-NEXT: cmp w9, w1, sxtb -; CHECK-NOLSE-O1-NEXT: csel w9, w8, w1, le +; CHECK-NOLSE-O1-NEXT: csel w9, w8, w1, lt ; CHECK-NOLSE-O1-NEXT: stxrb w10, w9, [x0] ; CHECK-NOLSE-O1-NEXT: cbnz w10, LBB33_1 ; CHECK-NOLSE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -2435,7 +2435,7 @@ define i8 @atomicrmw_min_i8(ptr %ptr, i8 %rhs) { ; CHECK-OUTLINE-O1-NEXT: ldaxrb w8, [x0] ; CHECK-OUTLINE-O1-NEXT: sxtb w9, w8 ; CHECK-OUTLINE-O1-NEXT: cmp w9, w1, sxtb -; CHECK-OUTLINE-O1-NEXT: csel w9, w8, w1, le +; CHECK-OUTLINE-O1-NEXT: csel w9, w8, w1, lt ; CHECK-OUTLINE-O1-NEXT: stxrb w10, w9, [x0] ; CHECK-OUTLINE-O1-NEXT: cbnz w10, LBB33_1 ; CHECK-OUTLINE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -2662,7 +2662,7 @@ define i8 @atomicrmw_umin_i8(ptr %ptr, i8 %rhs) { ; CHECK-NOLSE-O1-NEXT: ldaxrb w8, [x0] ; CHECK-NOLSE-O1-NEXT: and w10, w8, #0xff ; CHECK-NOLSE-O1-NEXT: cmp w10, w9 -; CHECK-NOLSE-O1-NEXT: csel w10, w10, w9, ls +; CHECK-NOLSE-O1-NEXT: csel w10, w10, w9, lo ; CHECK-NOLSE-O1-NEXT: stlxrb w11, w10, [x0] ; CHECK-NOLSE-O1-NEXT: cbnz w11, LBB35_1 ; CHECK-NOLSE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -2677,7 +2677,7 @@ define i8 @atomicrmw_umin_i8(ptr %ptr, i8 %rhs) { ; CHECK-OUTLINE-O1-NEXT: ldaxrb w8, [x0] ; CHECK-OUTLINE-O1-NEXT: and w10, w8, #0xff ; CHECK-OUTLINE-O1-NEXT: cmp w10, w9 -; CHECK-OUTLINE-O1-NEXT: csel w10, w10, w9, ls +; CHECK-OUTLINE-O1-NEXT: csel w10, w10, w9, lo ; CHECK-OUTLINE-O1-NEXT: stlxrb w11, w10, [x0] ; CHECK-OUTLINE-O1-NEXT: cbnz w11, LBB35_1 ; CHECK-OUTLINE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -3477,7 +3477,7 @@ define i16 @atomicrmw_min_i16(ptr %ptr, i16 %rhs) { ; CHECK-NOLSE-O1-NEXT: ldaxrh w8, [x0] ; CHECK-NOLSE-O1-NEXT: sxth w9, w8 ; CHECK-NOLSE-O1-NEXT: cmp w9, w1, sxth -; CHECK-NOLSE-O1-NEXT: csel w9, w8, w1, le +; CHECK-NOLSE-O1-NEXT: csel w9, w8, w1, lt ; CHECK-NOLSE-O1-NEXT: stxrh w10, w9, [x0] ; CHECK-NOLSE-O1-NEXT: cbnz w10, LBB43_1 ; CHECK-NOLSE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -3491,7 +3491,7 @@ define i16 @atomicrmw_min_i16(ptr %ptr, i16 %rhs) { ; CHECK-OUTLINE-O1-NEXT: ldaxrh w8, [x0] ; CHECK-OUTLINE-O1-NEXT: sxth w9, w8 ; CHECK-OUTLINE-O1-NEXT: cmp w9, w1, sxth -; CHECK-OUTLINE-O1-NEXT: csel w9, w8, w1, le +; CHECK-OUTLINE-O1-NEXT: csel w9, w8, w1, lt ; CHECK-OUTLINE-O1-NEXT: stxrh w10, w9, [x0] ; CHECK-OUTLINE-O1-NEXT: cbnz w10, LBB43_1 ; CHECK-OUTLINE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -3718,7 +3718,7 @@ define i16 @atomicrmw_umin_i16(ptr %ptr, i16 %rhs) { ; CHECK-NOLSE-O1-NEXT: ldaxrh w8, [x0] ; CHECK-NOLSE-O1-NEXT: and w10, w8, #0xffff ; CHECK-NOLSE-O1-NEXT: cmp w10, w9 -; CHECK-NOLSE-O1-NEXT: csel w10, w10, w9, ls +; CHECK-NOLSE-O1-NEXT: csel w10, w10, w9, lo ; CHECK-NOLSE-O1-NEXT: stlxrh w11, w10, [x0] ; CHECK-NOLSE-O1-NEXT: cbnz w11, LBB45_1 ; CHECK-NOLSE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -3733,7 +3733,7 @@ define i16 @atomicrmw_umin_i16(ptr %ptr, i16 %rhs) { ; CHECK-OUTLINE-O1-NEXT: ldaxrh w8, [x0] ; CHECK-OUTLINE-O1-NEXT: and w10, w8, #0xffff ; CHECK-OUTLINE-O1-NEXT: cmp w10, w9 -; CHECK-OUTLINE-O1-NEXT: csel w10, w10, w9, ls +; CHECK-OUTLINE-O1-NEXT: csel w10, w10, w9, lo ; CHECK-OUTLINE-O1-NEXT: stlxrh w11, w10, [x0] ; CHECK-OUTLINE-O1-NEXT: cbnz w11, LBB45_1 ; CHECK-OUTLINE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -4526,7 +4526,7 @@ define i32 @atomicrmw_min_i32(ptr %ptr, i32 %rhs) { ; CHECK-NOLSE-O1-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NOLSE-O1-NEXT: ldaxr w8, [x0] ; CHECK-NOLSE-O1-NEXT: cmp w8, w1 -; CHECK-NOLSE-O1-NEXT: csel w9, w8, w1, le +; CHECK-NOLSE-O1-NEXT: csel w9, w8, w1, lt ; CHECK-NOLSE-O1-NEXT: stxr w10, w9, [x0] ; CHECK-NOLSE-O1-NEXT: cbnz w10, LBB53_1 ; CHECK-NOLSE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -4539,7 +4539,7 @@ define i32 @atomicrmw_min_i32(ptr %ptr, i32 %rhs) { ; CHECK-OUTLINE-O1-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-OUTLINE-O1-NEXT: ldaxr w8, [x0] ; CHECK-OUTLINE-O1-NEXT: cmp w8, w1 -; CHECK-OUTLINE-O1-NEXT: csel w9, w8, w1, le +; CHECK-OUTLINE-O1-NEXT: csel w9, w8, w1, lt ; CHECK-OUTLINE-O1-NEXT: stxr w10, w9, [x0] ; CHECK-OUTLINE-O1-NEXT: cbnz w10, LBB53_1 ; CHECK-OUTLINE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -4754,7 +4754,7 @@ define i32 @atomicrmw_umin_i32(ptr %ptr, i32 %rhs) { ; CHECK-NOLSE-O1-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NOLSE-O1-NEXT: ldaxr w8, [x0] ; CHECK-NOLSE-O1-NEXT: cmp w8, w1 -; CHECK-NOLSE-O1-NEXT: csel w9, w8, w1, ls +; CHECK-NOLSE-O1-NEXT: csel w9, w8, w1, lo ; CHECK-NOLSE-O1-NEXT: stlxr w10, w9, [x0] ; CHECK-NOLSE-O1-NEXT: cbnz w10, LBB55_1 ; CHECK-NOLSE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -4767,7 +4767,7 @@ define i32 @atomicrmw_umin_i32(ptr %ptr, i32 %rhs) { ; CHECK-OUTLINE-O1-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-OUTLINE-O1-NEXT: ldaxr w8, [x0] ; CHECK-OUTLINE-O1-NEXT: cmp w8, w1 -; CHECK-OUTLINE-O1-NEXT: csel w9, w8, w1, ls +; CHECK-OUTLINE-O1-NEXT: csel w9, w8, w1, lo ; CHECK-OUTLINE-O1-NEXT: stlxr w10, w9, [x0] ; CHECK-OUTLINE-O1-NEXT: cbnz w10, LBB55_1 ; CHECK-OUTLINE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -5547,7 +5547,7 @@ define i64 @atomicrmw_min_i64(ptr %ptr, i64 %rhs) { ; CHECK-NOLSE-O1-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NOLSE-O1-NEXT: ldaxr x8, [x0] ; CHECK-NOLSE-O1-NEXT: cmp x8, x1 -; CHECK-NOLSE-O1-NEXT: csel x9, x8, x1, le +; CHECK-NOLSE-O1-NEXT: csel x9, x8, x1, lt ; CHECK-NOLSE-O1-NEXT: stxr w10, x9, [x0] ; CHECK-NOLSE-O1-NEXT: cbnz w10, LBB63_1 ; CHECK-NOLSE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -5560,7 +5560,7 @@ define i64 @atomicrmw_min_i64(ptr %ptr, i64 %rhs) { ; CHECK-OUTLINE-O1-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-OUTLINE-O1-NEXT: ldaxr x8, [x0] ; CHECK-OUTLINE-O1-NEXT: cmp x8, x1 -; CHECK-OUTLINE-O1-NEXT: csel x9, x8, x1, le +; CHECK-OUTLINE-O1-NEXT: csel x9, x8, x1, lt ; CHECK-OUTLINE-O1-NEXT: stxr w10, x9, [x0] ; CHECK-OUTLINE-O1-NEXT: cbnz w10, LBB63_1 ; CHECK-OUTLINE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -5775,7 +5775,7 @@ define i64 @atomicrmw_umin_i64(ptr %ptr, i64 %rhs) { ; CHECK-NOLSE-O1-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NOLSE-O1-NEXT: ldaxr x8, [x0] ; CHECK-NOLSE-O1-NEXT: cmp x8, x1 -; CHECK-NOLSE-O1-NEXT: csel x9, x8, x1, ls +; CHECK-NOLSE-O1-NEXT: csel x9, x8, x1, lo ; CHECK-NOLSE-O1-NEXT: stlxr w10, x9, [x0] ; CHECK-NOLSE-O1-NEXT: cbnz w10, LBB65_1 ; CHECK-NOLSE-O1-NEXT: ; %bb.2: ; %atomicrmw.end @@ -5788,7 +5788,7 @@ define i64 @atomicrmw_umin_i64(ptr %ptr, i64 %rhs) { ; CHECK-OUTLINE-O1-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-OUTLINE-O1-NEXT: ldaxr x8, [x0] ; CHECK-OUTLINE-O1-NEXT: cmp x8, x1 -; CHECK-OUTLINE-O1-NEXT: csel x9, x8, x1, ls +; CHECK-OUTLINE-O1-NEXT: csel x9, x8, x1, lo ; CHECK-OUTLINE-O1-NEXT: stlxr w10, x9, [x0] ; CHECK-OUTLINE-O1-NEXT: cbnz w10, LBB65_1 ; CHECK-OUTLINE-O1-NEXT: ; %bb.2: ; %atomicrmw.end diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-pcsections.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-pcsections.ll index 4c07081404c88..5a7bd6ee20f9b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-pcsections.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-pcsections.ll @@ -888,7 +888,7 @@ define i8 @atomicrmw_min_i8(ptr %ptr, i8 %rhs) { ; CHECK-NEXT: renamable $w8 = LDAXRB renamable $x0, implicit-def $x8, pcsections !0 :: (volatile load (s8) from %ir.ptr) ; CHECK-NEXT: renamable $w9 = SBFMWri renamable $w8, 0, 7, pcsections !0 ; CHECK-NEXT: dead $wzr = SUBSWrx killed renamable $w9, renamable $w1, 32, implicit-def $nzcv, pcsections !0 - ; CHECK-NEXT: renamable $w9 = CSELWr renamable $w8, renamable $w1, 13, implicit killed $nzcv, implicit-def $x9, pcsections !0 + ; CHECK-NEXT: renamable $w9 = CSELWr renamable $w8, renamable $w1, 11, implicit killed $nzcv, implicit-def $x9, pcsections !0 ; CHECK-NEXT: early-clobber renamable $w10 = STXRB renamable $w9, renamable $x0, implicit killed $x9, pcsections !0 :: (volatile store (s8) into %ir.ptr) ; CHECK-NEXT: CBNZW killed renamable $w10, %bb.1, pcsections !0 ; CHECK-NEXT: {{ $}} @@ -943,7 +943,7 @@ define i8 @atomicrmw_umin_i8(ptr %ptr, i8 %rhs) { ; CHECK-NEXT: renamable $w8 = LDAXRB renamable $x0, implicit-def $x8, pcsections !0 :: (volatile load (s8) from %ir.ptr) ; CHECK-NEXT: renamable $w10 = ANDWri renamable $w8, 7 ; CHECK-NEXT: $wzr = SUBSWrs renamable $w10, renamable $w9, 0, implicit-def $nzcv, pcsections !0 - ; CHECK-NEXT: renamable $w10 = CSELWr killed renamable $w10, renamable $w9, 9, implicit killed $nzcv, implicit-def $x10, pcsections !0 + ; CHECK-NEXT: renamable $w10 = CSELWr killed renamable $w10, renamable $w9, 3, implicit killed $nzcv, implicit-def $x10, pcsections !0 ; CHECK-NEXT: early-clobber renamable $w11 = STLXRB renamable $w10, renamable $x0, implicit killed $x10, pcsections !0 :: (volatile store (s8) into %ir.ptr) ; CHECK-NEXT: CBNZW killed renamable $w11, %bb.1, pcsections !0 ; CHECK-NEXT: {{ $}} @@ -1148,7 +1148,7 @@ define i16 @atomicrmw_min_i16(ptr %ptr, i16 %rhs) { ; CHECK-NEXT: renamable $w8 = LDAXRH renamable $x0, implicit-def $x8, pcsections !0 :: (volatile load (s16) from %ir.ptr) ; CHECK-NEXT: renamable $w9 = SBFMWri renamable $w8, 0, 15, pcsections !0 ; CHECK-NEXT: dead $wzr = SUBSWrx killed renamable $w9, renamable $w1, 40, implicit-def $nzcv, pcsections !0 - ; CHECK-NEXT: renamable $w9 = CSELWr renamable $w8, renamable $w1, 13, implicit killed $nzcv, implicit-def $x9, pcsections !0 + ; CHECK-NEXT: renamable $w9 = CSELWr renamable $w8, renamable $w1, 11, implicit killed $nzcv, implicit-def $x9, pcsections !0 ; CHECK-NEXT: early-clobber renamable $w10 = STXRH renamable $w9, renamable $x0, implicit killed $x9, pcsections !0 :: (volatile store (s16) into %ir.ptr) ; CHECK-NEXT: CBNZW killed renamable $w10, %bb.1, pcsections !0 ; CHECK-NEXT: {{ $}} @@ -1203,7 +1203,7 @@ define i16 @atomicrmw_umin_i16(ptr %ptr, i16 %rhs) { ; CHECK-NEXT: renamable $w8 = LDAXRH renamable $x0, implicit-def $x8, pcsections !0 :: (volatile load (s16) from %ir.ptr) ; CHECK-NEXT: renamable $w10 = ANDWri renamable $w8, 15 ; CHECK-NEXT: $wzr = SUBSWrs renamable $w10, renamable $w9, 0, implicit-def $nzcv, pcsections !0 - ; CHECK-NEXT: renamable $w10 = CSELWr killed renamable $w10, renamable $w9, 9, implicit killed $nzcv, implicit-def $x10, pcsections !0 + ; CHECK-NEXT: renamable $w10 = CSELWr killed renamable $w10, renamable $w9, 3, implicit killed $nzcv, implicit-def $x10, pcsections !0 ; CHECK-NEXT: early-clobber renamable $w11 = STLXRH renamable $w10, renamable $x0, implicit killed $x10, pcsections !0 :: (volatile store (s16) into %ir.ptr) ; CHECK-NEXT: CBNZW killed renamable $w11, %bb.1, pcsections !0 ; CHECK-NEXT: {{ $}} diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir index be2de620fa456..260cb72b0426a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir @@ -544,3 +544,284 @@ body: | %ext:_(s32) = G_ANYEXT %sel $w0 = COPY %ext(s32) ... +--- +# select test(failed,registers) select icmp_ugt t,f_t_f --> umax(t,f) +name: select_failed_icmp_ugt_t_f_t_f_umax_t_f +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_failed_icmp_ugt_t_f_t_f_umax_t_f + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2 + ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK-NEXT: %t:_(s8) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f:_(s8) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %y:_(s8) = G_TRUNC [[COPY2]](s64) + ; CHECK-NEXT: %z:_(s8) = G_TRUNC [[COPY3]](s64) + ; CHECK-NEXT: %c:_(s8) = G_ICMP intpred(ugt), %t(s8), %y + ; CHECK-NEXT: %sel:_(s8) = exact G_SELECT %c(s8), %f, %z + ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s8) + ; CHECK-NEXT: $w0 = COPY %ext(s32) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %2:_(s64) = COPY $x2 + %3:_(s64) = COPY $x3 + %4:_(s64) = COPY $x4 + %t:_(s8) = G_TRUNC %0 + %f:_(s8) = G_TRUNC %1 + %y:_(s8) = G_TRUNC %2 + %z:_(s8) = G_TRUNC %3 + %c:_(s8) = G_ICMP intpred(ugt), %t(s8), %y(s8) + %sel:_(s8) = exact G_SELECT %c, %f, %z + %ext:_(s32) = G_ANYEXT %sel + $w0 = COPY %ext(s32) +... +--- +# test select icmp_ugt t,f_t_f --> umax(t,f) +name: select_icmp_ugt_t_f_t_f_umax_t_f +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_icmp_ugt_t_f_t_f_umax_t_f + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: %t1:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) + ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) + ; CHECK-NEXT: %sel:_(<4 x s32>) = G_UMAX %t, %f + ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %t1:_(s32) = G_TRUNC %0 + %f1:_(s32) = G_TRUNC %1 + %t:_(<4 x s32>) = G_BUILD_VECTOR %t1, %t1, %t1, %t1 + %f:_(<4 x s32>) = G_BUILD_VECTOR %f1, %f1, %f1, %f1 + %c:_(<4 x s32>) = G_ICMP intpred(ugt), %t(<4 x s32>), %f(<4 x s32>) + %sel:_(<4 x s32>) = exact G_SELECT %c, %t, %f + $q0 = COPY %sel(<4 x s32>) +... +--- +# test select icmp_uge t,f_t_f --> umax(t,f) +name: select_icmp_uge_t_f_t_f_umax_t_f +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_icmp_uge_t_f_t_f_umax_t_f + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: %t1:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) + ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) + ; CHECK-NEXT: %sel:_(<4 x s32>) = G_UMAX %t, %f + ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %t1:_(s32) = G_TRUNC %0 + %f1:_(s32) = G_TRUNC %1 + %t:_(<4 x s32>) = G_BUILD_VECTOR %t1, %t1, %t1, %t1 + %f:_(<4 x s32>) = G_BUILD_VECTOR %f1, %f1, %f1, %f1 + %c:_(<4 x s32>) = G_ICMP intpred(uge), %t(<4 x s32>), %f(<4 x s32>) + %sel:_(<4 x s32>) = exact G_SELECT %c, %t, %f + $q0 = COPY %sel(<4 x s32>) +... +--- +# test select icmp_sgt t,f_t_f --> smax(t,f) +name: select_icmp_sgt_t_f_t_f_smax_t_f +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_icmp_sgt_t_f_t_f_smax_t_f + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: %t1:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) + ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) + ; CHECK-NEXT: %sel:_(<4 x s32>) = G_SMAX %t, %f + ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %t1:_(s32) = G_TRUNC %0 + %f1:_(s32) = G_TRUNC %1 + %t:_(<4 x s32>) = G_BUILD_VECTOR %t1, %t1, %t1, %t1 + %f:_(<4 x s32>) = G_BUILD_VECTOR %f1, %f1, %f1, %f1 + %c:_(<4 x s32>) = G_ICMP intpred(sgt), %t(<4 x s32>), %f(<4 x s32>) + %sel:_(<4 x s32>) = exact G_SELECT %c, %t, %f + $q0 = COPY %sel(<4 x s32>) +... +--- +# test select icmp_sge t,f_t_f --> smax(t,f) +name: select_icmp_sge_t_f_t_f_smax_t_f +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_icmp_sge_t_f_t_f_smax_t_f + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: %t1:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) + ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) + ; CHECK-NEXT: %sel:_(<4 x s32>) = G_SMAX %t, %f + ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %t1:_(s32) = G_TRUNC %0 + %f1:_(s32) = G_TRUNC %1 + %t:_(<4 x s32>) = G_BUILD_VECTOR %t1, %t1, %t1, %t1 + %f:_(<4 x s32>) = G_BUILD_VECTOR %f1, %f1, %f1, %f1 + %c:_(<4 x s32>) = G_ICMP intpred(sge), %t(<4 x s32>), %f(<4 x s32>) + %sel:_(<4 x s32>) = exact G_SELECT %c, %t, %f + $q0 = COPY %sel(<4 x s32>) +... +--- +# test select icmp_ult t,f_t_f --> umin(t,f) +name: select_icmp_ult_t_f_t_f_umin_t_f +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_icmp_ult_t_f_t_f_umin_t_f + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: %t1:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) + ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) + ; CHECK-NEXT: %sel:_(<4 x s32>) = G_UMIN %t, %f + ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %t1:_(s32) = G_TRUNC %0 + %f1:_(s32) = G_TRUNC %1 + %t:_(<4 x s32>) = G_BUILD_VECTOR %t1, %t1, %t1, %t1 + %f:_(<4 x s32>) = G_BUILD_VECTOR %f1, %f1, %f1, %f1 + %c:_(<4 x s32>) = G_ICMP intpred(ult), %t(<4 x s32>), %f(<4 x s32>) + %sel:_(<4 x s32>) = exact G_SELECT %c, %t, %f + $q0 = COPY %sel(<4 x s32>) +... +--- +# test select icmp_ule t,f_t_f --> umin(t,f) +name: select_icmp_ule_t_f_t_f_umin_t_f +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_icmp_ule_t_f_t_f_umin_t_f + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: %t1:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) + ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) + ; CHECK-NEXT: %sel:_(<4 x s32>) = G_UMIN %t, %f + ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %t1:_(s32) = G_TRUNC %0 + %f1:_(s32) = G_TRUNC %1 + %t:_(<4 x s32>) = G_BUILD_VECTOR %t1, %t1, %t1, %t1 + %f:_(<4 x s32>) = G_BUILD_VECTOR %f1, %f1, %f1, %f1 + %c:_(<4 x s32>) = G_ICMP intpred(ule), %t(<4 x s32>), %f(<4 x s32>) + %sel:_(<4 x s32>) = exact G_SELECT %c, %t, %f + $q0 = COPY %sel(<4 x s32>) +... +--- +# test select icmp_slt t,f_t_f --> smin(t,f) +name: select_icmp_slt_t_f_t_f_smin_t_f +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_icmp_slt_t_f_t_f_smin_t_f + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: %t1:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) + ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) + ; CHECK-NEXT: %sel:_(<4 x s32>) = G_SMIN %t, %f + ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %t1:_(s32) = G_TRUNC %0 + %f1:_(s32) = G_TRUNC %1 + %t:_(<4 x s32>) = G_BUILD_VECTOR %t1, %t1, %t1, %t1 + %f:_(<4 x s32>) = G_BUILD_VECTOR %f1, %f1, %f1, %f1 + %c:_(<4 x s32>) = G_ICMP intpred(slt), %t(<4 x s32>), %f(<4 x s32>) + %sel:_(<4 x s32>) = exact G_SELECT %c, %t, %f + $q0 = COPY %sel(<4 x s32>) +... +--- +# test select icmp_sle t,f_t_f --> smin(t,f) +name: select_icmp_sle_t_f_t_f_smin_t_f +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: select_icmp_sle_t_f_t_f_smin_t_f + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: %t1:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) + ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) + ; CHECK-NEXT: %sel:_(<4 x s32>) = G_SMIN %t, %f + ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %t1:_(s32) = G_TRUNC %0 + %f1:_(s32) = G_TRUNC %1 + %t:_(<4 x s32>) = G_BUILD_VECTOR %t1, %t1, %t1, %t1 + %f:_(<4 x s32>) = G_BUILD_VECTOR %f1, %f1, %f1, %f1 + %c:_(<4 x s32>) = G_ICMP intpred(sle), %t(<4 x s32>), %f(<4 x s32>) + %sel:_(<4 x s32>) = exact G_SELECT %c, %t, %f + $q0 = COPY %sel(<4 x s32>) +... +--- +# multi use test select icmp_sle t,f_t_f --> smin(t,f) failed +name: multi_use_select_icmp_sle_t_f_t_f_smin_t_f_failed +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; CHECK-LABEL: name: multi_use_select_icmp_sle_t_f_t_f_smin_t_f_failed + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK-NEXT: %t1:_(s32) = G_TRUNC [[COPY]](s64) + ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) + ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) + ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) + ; CHECK-NEXT: %c:_(<4 x s32>) = G_ICMP intpred(sle), %t(<4 x s32>), %f + ; CHECK-NEXT: $q1 = COPY %c(<4 x s32>) + ; CHECK-NEXT: %sel:_(<4 x s32>) = exact G_SELECT %c(<4 x s32>), %t, %f + ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) + %0:_(s64) = COPY $x0 + %1:_(s64) = COPY $x1 + %t1:_(s32) = G_TRUNC %0 + %f1:_(s32) = G_TRUNC %1 + %t:_(<4 x s32>) = G_BUILD_VECTOR %t1, %t1, %t1, %t1 + %f:_(<4 x s32>) = G_BUILD_VECTOR %f1, %f1, %f1, %f1 + %c:_(<4 x s32>) = G_ICMP intpred(sle), %t(<4 x s32>), %f(<4 x s32>) + $q1 = COPY %c(<4 x s32>) + %sel:_(<4 x s32>) = exact G_SELECT %c, %t, %f + $q0 = COPY %sel(<4 x s32>) +... From 9ef2ac3ad1bd5aa9e589f63047e8abeac11ad1b2 Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Thu, 11 Jan 2024 16:59:18 +0800 Subject: [PATCH 013/841] [clangd] Handle lambda scopes inside Node::getDeclContext() (#76329) We used to consider the `DeclContext` for selection nodes inside a lambda as the enclosing scope of the lambda expression, rather than the lambda itself. For example, ```cpp void foo(); auto lambda = [] { return ^foo(); }; ``` where `N` is the selection node for the expression `foo()`, `N.getDeclContext()` returns the `TranslationUnitDecl` previously, which IMO is wrong, since the method `operator()` of the lambda is closer. Incidentally, this fixes a glitch in add-using-declaration tweaks. (Thanks @HighCommander4 for the test case.) --- clang-tools-extra/clangd/Selection.cpp | 3 +++ .../clangd/unittests/SelectionTests.cpp | 13 +++++++++++ .../clangd/unittests/tweaks/AddUsingTests.cpp | 23 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp index 8c6d5750ecefd..277cb8769a1b1 100644 --- a/clang-tools-extra/clangd/Selection.cpp +++ b/clang-tools-extra/clangd/Selection.cpp @@ -1113,6 +1113,9 @@ const DeclContext &SelectionTree::Node::getDeclContext() const { return *DC; return *Current->getLexicalDeclContext(); } + if (const auto *LE = CurrentNode->ASTNode.get()) + if (CurrentNode != this) + return *LE->getCallOperator(); } llvm_unreachable("A tree must always be rooted at TranslationUnitDecl."); } diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp index 4c019a1524f3c..754e8c287c514 100644 --- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -880,6 +880,19 @@ TEST(SelectionTest, DeclContextIsLexical) { } } +TEST(SelectionTest, DeclContextLambda) { + llvm::Annotations Test(R"cpp( + void foo(); + auto lambda = [] { + return $1^foo(); + }; + )cpp"); + auto AST = TestTU::withCode(Test.code()).build(); + auto ST = SelectionTree::createRight(AST.getASTContext(), AST.getTokens(), + Test.point("1"), Test.point("1")); + EXPECT_TRUE(ST.commonAncestor()->getDeclContext().isFunctionOrMethod()); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp index 1fd2487378d70..c2dd8e1bb8eef 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/AddUsingTests.cpp @@ -309,6 +309,29 @@ namespace foo { void fun(); } void foo::fun() { ff(); })cpp"}, + // Inside a lambda. + { + R"cpp( +namespace NS { +void unrelated(); +void foo(); +} + +auto L = [] { + using NS::unrelated; + NS::f^oo(); +};)cpp", + R"cpp( +namespace NS { +void unrelated(); +void foo(); +} + +auto L = [] { + using NS::foo;using NS::unrelated; + foo(); +};)cpp", + }, // If all other using are fully qualified, add :: {R"cpp( #include "test.hpp" From ee431288a6639b3bdc07b819f5d584bfb39793ed Mon Sep 17 00:00:00 2001 From: Dominik Adamski Date: Thu, 11 Jan 2024 10:18:11 +0100 Subject: [PATCH 014/841] [NFC][OpenMP][Flang] Add smoke test for omp target parallel (#77579) Added test which proves that end-to-end compilation of omp target parallel costruct is successful for Flang compiler. --- .../fortran/basic-target-parallel-region.f90 | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 openmp/libomptarget/test/offloading/fortran/basic-target-parallel-region.f90 diff --git a/openmp/libomptarget/test/offloading/fortran/basic-target-parallel-region.f90 b/openmp/libomptarget/test/offloading/fortran/basic-target-parallel-region.f90 new file mode 100644 index 0000000000000..54341f7c40ff3 --- /dev/null +++ b/openmp/libomptarget/test/offloading/fortran/basic-target-parallel-region.f90 @@ -0,0 +1,21 @@ +! Basic offloading test with a target region +! REQUIRES: flang +! UNSUPPORTED: nvptx64-nvidia-cuda-LTO +! UNSUPPORTED: aarch64-unknown-linux-gnu +! UNSUPPORTED: aarch64-unknown-linux-gnu-LTO +! UNSUPPORTED: x86_64-pc-linux-gnu +! UNSUPPORTED: x86_64-pc-linux-gnu-LTO + +! RUN: %libomptarget-compile-fortran-run-and-check-generic +program main + use omp_lib + integer :: x + + !$omp target parallel map(from: x) + x = omp_get_num_threads() + !$omp end target parallel + print *,"parallel = ", (x .ne. 1) + +end program main + +! CHECK: parallel = T From 33e5db6e045d3a82e29a7c6ebffe259dfafefb3d Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Thu, 11 Jan 2024 10:19:44 +0100 Subject: [PATCH 015/841] [clang] Improve colors in status tracking web pages. Use a consistent, more pastel color for unknown status in papers and issues tracking pages --- clang/.clang-tidy | 2 +- clang/www/c_dr_status.html | 4 +- clang/www/c_status.html | 2 +- clang/www/cxx_dr_status.html | 3239 ++++++++++---------- clang/www/make_cxx_dr_status | 3 +- llvm/cmake/modules/HandleLLVMOptions.cmake | 2 +- 6 files changed, 1627 insertions(+), 1625 deletions(-) diff --git a/clang/.clang-tidy b/clang/.clang-tidy index ba55beb095f54..7eef110c3cf7e 100644 --- a/clang/.clang-tidy +++ b/clang/.clang-tidy @@ -1,5 +1,5 @@ # Note that the readability-identifier-naming check is disabled, there are too # many violations in the codebase and they create too much noise in clang-tidy # results. -Checks: '-readability-identifier-naming' +Checks: '-readability-identifier-naming, -misc-include*' InheritParentConfig: true diff --git a/clang/www/c_dr_status.html b/clang/www/c_dr_status.html index 4fe088e297750..fa2ceb1be58bd 100644 --- a/clang/www/c_dr_status.html +++ b/clang/www/c_dr_status.html @@ -12,7 +12,7 @@ .unreleased { background-color: #FFFF99 } .full { background-color: #CCFF99 } .na { background-color: #DDDDDD } - .unknown { background-color: #FF55FF } + .unknown { background-color: #EBCAFE } .open * { color: #AAAAAA } //.open { filter: opacity(0.2) } tr:target { background-color: #FFFFBB } @@ -35,7 +35,7 @@

C defect report implementation status

The implementation status for defect reports against the C Standard are currently under investigation. Any defect report whose status in Clang is -currently unknown will be marked in magenta.

+currently unknown will be marked in purple.

The LLVM bug tracker uses the "c", "c99", "c11", "c17", and "c23" labels to track known bugs with Clang's language diff --git a/clang/www/c_status.html b/clang/www/c_status.html index 47acb1f87b8e3..fe56bc791ccbe 100644 --- a/clang/www/c_status.html +++ b/clang/www/c_status.html @@ -9,7 +9,7 @@ .none { background-color: #FFCCCC } .partial { background-color: #FFE0B0 } .unreleased { background-color: #FFFF99 } - .unknown { background-color: #FF55FF } + .unknown { background-color: #DDAEF7 } .full { background-color: #CCFF99 } .na { background-color: #DDDDDD } :target { background-color: #FFFFBB; outline: #DDDD55 solid thin; } diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 2bded63d5cd41..4a3ed19161f9a 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -8,6 +8,7 @@