diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 77ba81c58c5d63..76b8266cae87c4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -125,3 +125,6 @@ clang/test/AST/Interp/ @tbaederr /llvm/**/TextAPI/ @cyndyishida /clang/**/InstallAPI/ @cyndyishida /clang/tools/clang-installapi/ @cyndyishida + +# ExtractAPI +/clang/**/ExtractAPI @daniel-grumberg diff --git a/.github/workflows/issue-write.yml b/.github/workflows/issue-write.yml index 02a5f7c213e898..4a564a5076bac9 100644 --- a/.github/workflows/issue-write.yml +++ b/.github/workflows/issue-write.yml @@ -31,7 +31,7 @@ jobs: script: | var fs = require('fs'); const comments = JSON.parse(fs.readFileSync('./comments')); - if (!comments) { + if (!comments || comments.length == 0) { return; } @@ -77,6 +77,15 @@ jobs: } const gql_result = await github.graphql(gql_query, gql_variables); console.log(gql_result); + // If the branch for the PR was deleted before this job has a chance + // to run, then the ref will be null. This can happen if someone: + // 1. Rebase the PR, which triggers some workflow. + // 2. Immediately merges the PR and deletes the branch. + // 3. The workflow finishes and triggers this job. + if (!gql_result.repository.ref) { + console.log("Ref has been deleted"); + return; + } console.log(gql_result.repository.ref.associatedPullRequests.nodes); var pr_number = 0; diff --git a/.github/workflows/pr-code-format.yml b/.github/workflows/pr-code-format.yml index 54dfe3aadbb423..10b18f245d8965 100644 --- a/.github/workflows/pr-code-format.yml +++ b/.github/workflows/pr-code-format.yml @@ -33,7 +33,7 @@ jobs: - name: Fetch code formatting utils uses: actions/checkout@v4 with: - reository: ${{ github.repository }} + repository: ${{ github.repository }} ref: ${{ github.base_ref }} sparse-checkout: | llvm/utils/git/requirements_formatting.txt diff --git a/bolt/include/bolt/Core/AddressMap.h b/bolt/include/bolt/Core/AddressMap.h index 85a9ab4473aafe..31ed7d40ee7f21 100644 --- a/bolt/include/bolt/Core/AddressMap.h +++ b/bolt/include/bolt/Core/AddressMap.h @@ -14,7 +14,6 @@ #ifndef BOLT_CORE_ADDRESS_MAP_H #define BOLT_CORE_ADDRESS_MAP_H -#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCSymbol.h" #include diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h index 741b1a36af86f8..8b1af9e8153925 100644 --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -265,7 +265,8 @@ class BinaryContext { public: static Expected> - createBinaryContext(const ObjectFile *File, bool IsPIC, + createBinaryContext(Triple TheTriple, StringRef InputFileName, + SubtargetFeatures *Features, bool IsPIC, std::unique_ptr DwCtx, JournalingStreams Logger); diff --git a/bolt/include/bolt/Core/BinaryData.h b/bolt/include/bolt/Core/BinaryData.h index 5f1efda781905d..495163f1b61aaf 100644 --- a/bolt/include/bolt/Core/BinaryData.h +++ b/bolt/include/bolt/Core/BinaryData.h @@ -18,7 +18,6 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/raw_ostream.h" -#include #include #include diff --git a/bolt/include/bolt/Core/BinaryDomTree.h b/bolt/include/bolt/Core/BinaryDomTree.h index a9565795f94631..de27aa78769d23 100644 --- a/bolt/include/bolt/Core/BinaryDomTree.h +++ b/bolt/include/bolt/Core/BinaryDomTree.h @@ -16,7 +16,6 @@ #include "bolt/Core/BinaryBasicBlock.h" #include "llvm/IR/Dominators.h" -#include "llvm/Support/GenericDomTreeConstruction.h" namespace llvm { namespace bolt { diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h index c170fa6397cc92..bc047fefa3151c 100644 --- a/bolt/include/bolt/Core/BinaryFunction.h +++ b/bolt/include/bolt/Core/BinaryFunction.h @@ -27,6 +27,7 @@ #include "bolt/Core/BinaryBasicBlock.h" #include "bolt/Core/BinaryContext.h" +#include "bolt/Core/BinaryDomTree.h" #include "bolt/Core/BinaryLoop.h" #include "bolt/Core/BinarySection.h" #include "bolt/Core/DebugData.h" @@ -51,7 +52,6 @@ #include #include #include -#include #include #include @@ -266,6 +266,7 @@ class BinaryFunction { BinaryContext &BC; std::unique_ptr BLI; + std::unique_ptr BDT; /// All labels in the function that are referenced via relocations from /// data objects. Typically these are jump table destinations and computed @@ -838,6 +839,14 @@ class BinaryFunction { /// stats. void calculateMacroOpFusionStats(); + /// Returns if BinaryDominatorTree has been constructed for this function. + bool hasDomTree() const { return BDT != nullptr; } + + BinaryDominatorTree &getDomTree() { return *BDT.get(); } + + /// Constructs DomTree for this function. + void constructDomTree(); + /// Returns if loop detection has been run for this function. bool hasLoopInfo() const { return BLI != nullptr; } @@ -1159,7 +1168,7 @@ class BinaryFunction { /// Pass an offset of the entry point in the input binary and a corresponding /// global symbol to the callback function. /// - /// Return true of all callbacks returned true, false otherwise. + /// Return true if all callbacks returned true, false otherwise. bool forEachEntryPoint(EntryPointCallbackTy Callback) const; /// Return MC symbol associated with the end of the function. diff --git a/bolt/include/bolt/Core/BinaryLoop.h b/bolt/include/bolt/Core/BinaryLoop.h index 72dce77df8c14b..b425c75715d8b1 100644 --- a/bolt/include/bolt/Core/BinaryLoop.h +++ b/bolt/include/bolt/Core/BinaryLoop.h @@ -15,7 +15,7 @@ #ifndef BOLT_CORE_BINARY_LOOP_H #define BOLT_CORE_BINARY_LOOP_H -#include "llvm/Support/GenericLoopInfoImpl.h" +#include "llvm/Support/GenericLoopInfo.h" namespace llvm { namespace bolt { diff --git a/bolt/include/bolt/Core/BinarySection.h b/bolt/include/bolt/Core/BinarySection.h index 0f179877bd3df3..5b7a5b08820e6e 100644 --- a/bolt/include/bolt/Core/BinarySection.h +++ b/bolt/include/bolt/Core/BinarySection.h @@ -18,7 +18,6 @@ #include "bolt/Core/DebugData.h" #include "bolt/Core/Relocation.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h index 7d10b208dc83a2..166bb3617e57f6 100644 --- a/bolt/include/bolt/Core/DebugData.h +++ b/bolt/include/bolt/Core/DebugData.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include diff --git a/bolt/include/bolt/Core/DebugNames.h b/bolt/include/bolt/Core/DebugNames.h index fbaa7f4e68aac9..a4fdde7c396ad8 100644 --- a/bolt/include/bolt/Core/DebugNames.h +++ b/bolt/include/bolt/Core/DebugNames.h @@ -14,7 +14,7 @@ #ifndef BOLT_CORE_DEBUG_NAMES_H #define BOLT_CORE_DEBUG_NAMES_H -#include "DebugData.h" +#include "bolt/Core/DebugData.h" #include "llvm/CodeGen/AccelTable.h" namespace llvm { diff --git a/bolt/include/bolt/Core/FunctionLayout.h b/bolt/include/bolt/Core/FunctionLayout.h index 2e4c184ba4511c..b685a99c79c14c 100644 --- a/bolt/include/bolt/Core/FunctionLayout.h +++ b/bolt/include/bolt/Core/FunctionLayout.h @@ -25,7 +25,6 @@ #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include -#include namespace llvm { namespace bolt { diff --git a/bolt/include/bolt/Core/MCPlus.h b/bolt/include/bolt/Core/MCPlus.h index 1d2360c180335f..601d709712864e 100644 --- a/bolt/include/bolt/Core/MCPlus.h +++ b/bolt/include/bolt/Core/MCPlus.h @@ -14,10 +14,8 @@ #ifndef BOLT_CORE_MCPLUS_H #define BOLT_CORE_MCPLUS_H -#include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" -#include "llvm/Support/Casting.h" #include namespace llvm { diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h index 198a8d8bf48f82..f7614cf9ac9777 100644 --- a/bolt/include/bolt/Core/MCPlusBuilder.h +++ b/bolt/include/bolt/Core/MCPlusBuilder.h @@ -19,6 +19,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/CodeGen/TargetOpcodes.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCDisassembler/MCSymbolizer.h" #include "llvm/MC/MCExpr.h" @@ -27,6 +28,7 @@ #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/RWMutex.h" @@ -533,9 +535,7 @@ class MCPlusBuilder { return Analysis->isReturn(Inst); } - virtual bool isTerminator(const MCInst &Inst) const { - return Analysis->isTerminator(Inst); - } + virtual bool isTerminator(const MCInst &Inst) const; virtual bool isNoop(const MCInst &Inst) const { llvm_unreachable("not implemented"); diff --git a/bolt/include/bolt/Passes/BinaryPasses.h b/bolt/include/bolt/Passes/BinaryPasses.h index 046765b16f19d2..8d89ef8b5484f8 100644 --- a/bolt/include/bolt/Passes/BinaryPasses.h +++ b/bolt/include/bolt/Passes/BinaryPasses.h @@ -18,7 +18,6 @@ #include "bolt/Core/DynoStats.h" #include "llvm/Support/CommandLine.h" #include -#include #include #include #include diff --git a/bolt/include/bolt/Passes/CacheMetrics.h b/bolt/include/bolt/Passes/CacheMetrics.h index 5c88d98c76c1d5..ea56d330446b99 100644 --- a/bolt/include/bolt/Passes/CacheMetrics.h +++ b/bolt/include/bolt/Passes/CacheMetrics.h @@ -13,7 +13,6 @@ #ifndef BOLT_PASSES_CACHEMETRICS_H #define BOLT_PASSES_CACHEMETRICS_H -#include #include namespace llvm { diff --git a/bolt/include/bolt/Passes/DominatorAnalysis.h b/bolt/include/bolt/Passes/DominatorAnalysis.h index c2b5c3af014722..3f3afa943c06ce 100644 --- a/bolt/include/bolt/Passes/DominatorAnalysis.h +++ b/bolt/include/bolt/Passes/DominatorAnalysis.h @@ -11,7 +11,6 @@ #include "bolt/Passes/DataflowAnalysis.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Timer.h" namespace opts { extern llvm::cl::opt TimeOpts; diff --git a/bolt/include/bolt/Passes/ReachingDefOrUse.h b/bolt/include/bolt/Passes/ReachingDefOrUse.h index f38d1a373e18b8..585d673e3b84e5 100644 --- a/bolt/include/bolt/Passes/ReachingDefOrUse.h +++ b/bolt/include/bolt/Passes/ReachingDefOrUse.h @@ -11,9 +11,7 @@ #include "bolt/Passes/DataflowAnalysis.h" #include "bolt/Passes/RegAnalysis.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Timer.h" #include namespace opts { diff --git a/bolt/include/bolt/Passes/ReachingInsns.h b/bolt/include/bolt/Passes/ReachingInsns.h index 65782b12064b85..ef878f5e452db3 100644 --- a/bolt/include/bolt/Passes/ReachingInsns.h +++ b/bolt/include/bolt/Passes/ReachingInsns.h @@ -11,7 +11,6 @@ #include "bolt/Passes/DataflowAnalysis.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Timer.h" namespace opts { extern llvm::cl::opt TimeOpts; diff --git a/bolt/include/bolt/Passes/ReorderUtils.h b/bolt/include/bolt/Passes/ReorderUtils.h index bc82b4f436fa75..8ceb8ba62690a5 100644 --- a/bolt/include/bolt/Passes/ReorderUtils.h +++ b/bolt/include/bolt/Passes/ReorderUtils.h @@ -14,7 +14,6 @@ #ifndef BOLT_PASSES_REORDER_UTILS_H #define BOLT_PASSES_REORDER_UTILS_H -#include #include #include "llvm/ADT/BitVector.h" diff --git a/bolt/include/bolt/Profile/ProfileReaderBase.h b/bolt/include/bolt/Profile/ProfileReaderBase.h index 511718f3c0ec74..3e5cf261289390 100644 --- a/bolt/include/bolt/Profile/ProfileReaderBase.h +++ b/bolt/include/bolt/Profile/ProfileReaderBase.h @@ -65,7 +65,7 @@ class ProfileReaderBase { /// Return true if the function \p BF may have a profile available. /// The result is based on the name(s) of the function alone and the profile /// match is not guaranteed. - virtual bool mayHaveProfileData(const BinaryFunction &BF); + virtual bool mayHaveProfileData(const BinaryFunction &BF) { return true; } /// Return true if the profile contains an entry for a local object /// that has an associated file name. diff --git a/bolt/include/bolt/Profile/ProfileYAMLMapping.h b/bolt/include/bolt/Profile/ProfileYAMLMapping.h index 548b528ae2d653..9dd3920dbf0943 100644 --- a/bolt/include/bolt/Profile/ProfileYAMLMapping.h +++ b/bolt/include/bolt/Profile/ProfileYAMLMapping.h @@ -14,7 +14,6 @@ #define BOLT_PROFILE_PROFILEYAMLMAPPING_H #include "bolt/Core/BinaryFunction.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/YAMLTraits.h" #include diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h index 20972f3d0b85ae..2c482bd2b9ea96 100644 --- a/bolt/include/bolt/Rewrite/DWARFRewriter.h +++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h @@ -22,9 +22,7 @@ #include #include #include -#include #include -#include #include namespace llvm { diff --git a/bolt/include/bolt/Rewrite/MetadataManager.h b/bolt/include/bolt/Rewrite/MetadataManager.h index efbc74b4daba9d..2ff70dbaab3de7 100644 --- a/bolt/include/bolt/Rewrite/MetadataManager.h +++ b/bolt/include/bolt/Rewrite/MetadataManager.h @@ -11,7 +11,6 @@ #include "bolt/Rewrite/MetadataRewriter.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Error.h" namespace llvm { namespace bolt { diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h index 97ab65cd5a4a1f..826677cd63b22b 100644 --- a/bolt/include/bolt/Rewrite/RewriteInstance.h +++ b/bolt/include/bolt/Rewrite/RewriteInstance.h @@ -17,7 +17,6 @@ #include "bolt/Core/Linker.h" #include "bolt/Rewrite/MetadataManager.h" #include "bolt/Utils/NameResolver.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ObjectFile.h" diff --git a/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h b/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h index c845cb7f7b214d..e392029156bcea 100644 --- a/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h +++ b/bolt/include/bolt/RuntimeLibs/RuntimeLibrary.h @@ -17,7 +17,6 @@ #include "bolt/Core/Linker.h" #include "llvm/ADT/StringRef.h" -#include #include namespace llvm { diff --git a/bolt/include/bolt/Utils/NameShortener.h b/bolt/include/bolt/Utils/NameShortener.h index 9c7b7ec9ba655c..fd61235f93c86b 100644 --- a/bolt/include/bolt/Utils/NameShortener.h +++ b/bolt/include/bolt/Utils/NameShortener.h @@ -14,7 +14,6 @@ #define BOLT_UTILS_NAME_SHORTENER_H #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/Twine.h" namespace llvm { namespace bolt { diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp index 267f43f65e206e..47eae964e816c5 100644 --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -14,7 +14,6 @@ #include "bolt/Core/BinaryEmitter.h" #include "bolt/Core/BinaryFunction.h" #include "bolt/Utils/CommandLineOpts.h" -#include "bolt/Utils/NameResolver.h" #include "bolt/Utils/Utils.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" @@ -39,7 +38,6 @@ #include #include #include -#include #include using namespace llvm; @@ -162,28 +160,30 @@ BinaryContext::~BinaryContext() { /// Create BinaryContext for a given architecture \p ArchName and /// triple \p TripleName. -Expected> -BinaryContext::createBinaryContext(const ObjectFile *File, bool IsPIC, - std::unique_ptr DwCtx, - JournalingStreams Logger) { +Expected> BinaryContext::createBinaryContext( + Triple TheTriple, StringRef InputFileName, SubtargetFeatures *Features, + bool IsPIC, std::unique_ptr DwCtx, JournalingStreams Logger) { StringRef ArchName = ""; std::string FeaturesStr = ""; - switch (File->getArch()) { + switch (TheTriple.getArch()) { case llvm::Triple::x86_64: + if (Features) + return createFatalBOLTError( + "x86_64 target does not use SubtargetFeatures"); ArchName = "x86-64"; FeaturesStr = "+nopl"; break; case llvm::Triple::aarch64: + if (Features) + return createFatalBOLTError( + "AArch64 target does not use SubtargetFeatures"); ArchName = "aarch64"; FeaturesStr = "+all"; break; case llvm::Triple::riscv64: { ArchName = "riscv64"; - Expected Features = File->getFeatures(); - - if (auto E = Features.takeError()) - return std::move(E); - + if (!Features) + return createFatalBOLTError("RISCV target needs SubtargetFeatures"); // We rely on relaxation for some transformations (e.g., promoting all calls // to PseudoCALL and then making JITLink relax them). Since the relax // feature is not stored in the object file, we manually enable it. @@ -196,12 +196,11 @@ BinaryContext::createBinaryContext(const ObjectFile *File, bool IsPIC, "BOLT-ERROR: Unrecognized machine in ELF file"); } - auto TheTriple = std::make_unique(File->makeTriple()); - const std::string TripleName = TheTriple->str(); + const std::string TripleName = TheTriple.str(); std::string Error; const Target *TheTarget = - TargetRegistry::lookupTarget(std::string(ArchName), *TheTriple, Error); + TargetRegistry::lookupTarget(std::string(ArchName), TheTriple, Error); if (!TheTarget) return createStringError(make_error_code(std::errc::not_supported), Twine("BOLT-ERROR: ", Error)); @@ -240,13 +239,13 @@ BinaryContext::createBinaryContext(const ObjectFile *File, bool IsPIC, Twine("BOLT-ERROR: no instruction info for target ", TripleName)); std::unique_ptr Ctx( - new MCContext(*TheTriple, AsmInfo.get(), MRI.get(), STI.get())); + new MCContext(TheTriple, AsmInfo.get(), MRI.get(), STI.get())); std::unique_ptr MOFI( TheTarget->createMCObjectFileInfo(*Ctx, IsPIC)); Ctx->setObjectFileInfo(MOFI.get()); // We do not support X86 Large code model. Change this in the future. bool Large = false; - if (TheTriple->getArch() == llvm::Triple::aarch64) + if (TheTriple.getArch() == llvm::Triple::aarch64) Large = true; unsigned LSDAEncoding = Large ? dwarf::DW_EH_PE_absptr : dwarf::DW_EH_PE_udata4; @@ -273,7 +272,7 @@ BinaryContext::createBinaryContext(const ObjectFile *File, bool IsPIC, int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); std::unique_ptr InstructionPrinter( - TheTarget->createMCInstPrinter(*TheTriple, AsmPrinterVariant, *AsmInfo, + TheTarget->createMCInstPrinter(TheTriple, AsmPrinterVariant, *AsmInfo, *MII, *MRI)); if (!InstructionPrinter) return createStringError( @@ -285,8 +284,8 @@ BinaryContext::createBinaryContext(const ObjectFile *File, bool IsPIC, TheTarget->createMCCodeEmitter(*MII, *Ctx)); auto BC = std::make_unique( - std::move(Ctx), std::move(DwCtx), std::move(TheTriple), TheTarget, - std::string(TripleName), std::move(MCE), std::move(MOFI), + std::move(Ctx), std::move(DwCtx), std::make_unique(TheTriple), + TheTarget, std::string(TripleName), std::move(MCE), std::move(MOFI), std::move(AsmInfo), std::move(MII), std::move(STI), std::move(InstructionPrinter), std::move(MIA), nullptr, std::move(MRI), std::move(DisAsm), Logger); @@ -296,7 +295,7 @@ BinaryContext::createBinaryContext(const ObjectFile *File, bool IsPIC, BC->MAB = std::unique_ptr( BC->TheTarget->createMCAsmBackend(*BC->STI, *BC->MRI, MCTargetOptions())); - BC->setFilename(File->getFileName()); + BC->setFilename(InputFileName); BC->HasFixedLoadAddress = !IsPIC; diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp index c9e037c225dd41..1fa96dfaabde81 100644 --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -12,7 +12,6 @@ #include "bolt/Core/BinaryFunction.h" #include "bolt/Core/BinaryBasicBlock.h" -#include "bolt/Core/BinaryDomTree.h" #include "bolt/Core/DynoStats.h" #include "bolt/Core/HashUtilities.h" #include "bolt/Core/MCPlusBuilder.h" @@ -35,6 +34,8 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/GenericDomTreeConstruction.h" +#include "llvm/Support/GenericLoopInfoImpl.h" #include "llvm/Support/GraphWriter.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/Regex.h" @@ -4076,12 +4077,17 @@ BinaryFunction::~BinaryFunction() { delete BB; } +void BinaryFunction::constructDomTree() { + BDT.reset(new BinaryDominatorTree); + BDT->recalculate(*this); +} + void BinaryFunction::calculateLoopInfo() { + if (!hasDomTree()) + constructDomTree(); // Discover loops. - BinaryDominatorTree DomTree; - DomTree.recalculate(*this); BLI.reset(new BinaryLoopInfo()); - BLI->analyze(DomTree); + BLI->analyze(getDomTree()); // Traverse discovered loops and add depth and profile information. std::stack St; diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp index 354fe5059443cc..c4b0b251c1201f 100644 --- a/bolt/lib/Core/DIEBuilder.cpp +++ b/bolt/lib/Core/DIEBuilder.cpp @@ -22,7 +22,6 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Format.h" #include "llvm/Support/LEB128.h" #include diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp index a75016ede3090d..a987a103a08b93 100644 --- a/bolt/lib/Core/DebugData.cpp +++ b/bolt/lib/Core/DebugData.cpp @@ -13,7 +13,6 @@ #include "bolt/Core/DebugData.h" #include "bolt/Core/BinaryContext.h" #include "bolt/Core/DIEBuilder.h" -#include "bolt/Rewrite/RewriteInstance.h" #include "bolt/Utils/Utils.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/DIE.h" @@ -23,7 +22,6 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectStreamer.h" -#include "llvm/Support/Allocator.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/LEB128.h" @@ -32,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/bolt/lib/Core/FunctionLayout.cpp b/bolt/lib/Core/FunctionLayout.cpp index 27e40de94be660..73f4d5247d9ac0 100644 --- a/bolt/lib/Core/FunctionLayout.cpp +++ b/bolt/lib/Core/FunctionLayout.cpp @@ -1,12 +1,17 @@ +//===- bolt/Core/FunctionLayout.cpp - Fragmented Function Layout -*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #include "bolt/Core/FunctionLayout.h" -#include "bolt/Core/BinaryFunction.h" +#include "bolt/Core/BinaryBasicBlock.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/edit_distance.h" #include -#include -#include #include -#include using namespace llvm; using namespace bolt; diff --git a/bolt/lib/Core/HashUtilities.cpp b/bolt/lib/Core/HashUtilities.cpp index d40159b2e216d9..c4c67bd68198b6 100644 --- a/bolt/lib/Core/HashUtilities.cpp +++ b/bolt/lib/Core/HashUtilities.cpp @@ -12,7 +12,6 @@ #include "bolt/Core/HashUtilities.h" #include "bolt/Core/BinaryContext.h" -#include "bolt/Core/BinaryFunction.h" #include "llvm/MC/MCInstPrinter.h" namespace llvm { diff --git a/bolt/lib/Core/MCPlusBuilder.cpp b/bolt/lib/Core/MCPlusBuilder.cpp index 5b14ad5cdb880f..7ff7a2288451c8 100644 --- a/bolt/lib/Core/MCPlusBuilder.cpp +++ b/bolt/lib/Core/MCPlusBuilder.cpp @@ -12,15 +12,16 @@ #include "bolt/Core/MCPlusBuilder.h" #include "bolt/Core/MCPlus.h" +#include "bolt/Utils/CommandLineOpts.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include -#include #define DEBUG_TYPE "mcplus" @@ -28,6 +29,13 @@ using namespace llvm; using namespace bolt; using namespace MCPlus; +namespace opts { +cl::opt + TerminalTrap("terminal-trap", + cl::desc("Assume that execution stops at trap instruction"), + cl::init(true), cl::Hidden, cl::cat(BoltCategory)); +} + bool MCPlusBuilder::equals(const MCInst &A, const MCInst &B, CompFuncTy Comp) const { if (A.getOpcode() != B.getOpcode()) @@ -121,6 +129,11 @@ bool MCPlusBuilder::equals(const MCTargetExpr &A, const MCTargetExpr &B, llvm_unreachable("target-specific expressions are unsupported"); } +bool MCPlusBuilder::isTerminator(const MCInst &Inst) const { + return Analysis->isTerminator(Inst) || + (opts::TerminalTrap && Info->get(Inst.getOpcode()).isTrap()); +} + void MCPlusBuilder::setTailCall(MCInst &Inst) const { assert(!hasAnnotation(Inst, MCAnnotation::kTailCall)); setAnnotationOpValue(Inst, MCAnnotation::kTailCall, true); diff --git a/bolt/lib/Passes/CMOVConversion.cpp b/bolt/lib/Passes/CMOVConversion.cpp index 2492ff21794634..cdd99b55207e0b 100644 --- a/bolt/lib/Passes/CMOVConversion.cpp +++ b/bolt/lib/Passes/CMOVConversion.cpp @@ -17,7 +17,6 @@ #include "llvm/ADT/PostOrderIterator.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" -#include #define DEBUG_TYPE "cmov" diff --git a/bolt/lib/Passes/FixRISCVCallsPass.cpp b/bolt/lib/Passes/FixRISCVCallsPass.cpp index 83c745facb290b..9011ef303a80ef 100644 --- a/bolt/lib/Passes/FixRISCVCallsPass.cpp +++ b/bolt/lib/Passes/FixRISCVCallsPass.cpp @@ -1,3 +1,11 @@ +//===- bolt/Passes/FixRISCVCallsPass.cpp ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #include "bolt/Passes/FixRISCVCallsPass.h" #include "bolt/Core/ParallelUtilities.h" diff --git a/bolt/lib/Passes/FixRelaxationPass.cpp b/bolt/lib/Passes/FixRelaxationPass.cpp index a49fb9894e808c..7c970e464a94e3 100644 --- a/bolt/lib/Passes/FixRelaxationPass.cpp +++ b/bolt/lib/Passes/FixRelaxationPass.cpp @@ -1,3 +1,11 @@ +//===- bolt/Passes/FixRelaxationPass.cpp ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #include "bolt/Passes/FixRelaxationPass.h" #include "bolt/Core/ParallelUtilities.h" diff --git a/bolt/lib/Passes/FrameOptimizer.cpp b/bolt/lib/Passes/FrameOptimizer.cpp index fb5f8eafa5cf84..8461225e1819c1 100644 --- a/bolt/lib/Passes/FrameOptimizer.cpp +++ b/bolt/lib/Passes/FrameOptimizer.cpp @@ -20,7 +20,6 @@ #include "bolt/Utils/CommandLineOpts.h" #include "llvm/Support/Timer.h" #include -#include #define DEBUG_TYPE "fop" diff --git a/bolt/lib/Passes/Hugify.cpp b/bolt/lib/Passes/Hugify.cpp index b77356153bfd8c..1ac1b08573b869 100644 --- a/bolt/lib/Passes/Hugify.cpp +++ b/bolt/lib/Passes/Hugify.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "bolt/Passes/Hugify.h" -#include "llvm/Support/CommandLine.h" #define DEBUG_TYPE "bolt-hugify" diff --git a/bolt/lib/Passes/Inliner.cpp b/bolt/lib/Passes/Inliner.cpp index a3b2017aa32aa8..84e7d97067b0cf 100644 --- a/bolt/lib/Passes/Inliner.cpp +++ b/bolt/lib/Passes/Inliner.cpp @@ -27,7 +27,6 @@ #include "bolt/Passes/Inliner.h" #include "bolt/Core/MCPlus.h" #include "llvm/Support/CommandLine.h" -#include #define DEBUG_TYPE "bolt-inliner" diff --git a/bolt/lib/Passes/ShrinkWrapping.cpp b/bolt/lib/Passes/ShrinkWrapping.cpp index c9706500758d1f..176321c58dc903 100644 --- a/bolt/lib/Passes/ShrinkWrapping.cpp +++ b/bolt/lib/Passes/ShrinkWrapping.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "bolt/Passes/ShrinkWrapping.h" -#include "bolt/Core/MCPlus.h" #include "bolt/Passes/DataflowInfoManager.h" #include "bolt/Passes/MCF.h" #include "bolt/Utils/CommandLineOpts.h" diff --git a/bolt/lib/Passes/SplitFunctions.cpp b/bolt/lib/Passes/SplitFunctions.cpp index cdbb2a15f667c6..f9e634d15a9724 100644 --- a/bolt/lib/Passes/SplitFunctions.cpp +++ b/bolt/lib/Passes/SplitFunctions.cpp @@ -17,7 +17,6 @@ #include "bolt/Core/ParallelUtilities.h" #include "bolt/Utils/CommandLineOpts.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Sequence.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/CommandLine.h" diff --git a/bolt/lib/Passes/TailDuplication.cpp b/bolt/lib/Passes/TailDuplication.cpp index 2163e3a6a00836..463ea49527fa6c 100644 --- a/bolt/lib/Passes/TailDuplication.cpp +++ b/bolt/lib/Passes/TailDuplication.cpp @@ -13,9 +13,9 @@ #include "bolt/Passes/TailDuplication.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCRegisterInfo.h" -#include #include +#include #define DEBUG_TYPE "taildup" diff --git a/bolt/lib/Passes/ValidateInternalCalls.cpp b/bolt/lib/Passes/ValidateInternalCalls.cpp index 54ae621159cfa3..88df2e5b59f389 100644 --- a/bolt/lib/Passes/ValidateInternalCalls.cpp +++ b/bolt/lib/Passes/ValidateInternalCalls.cpp @@ -14,7 +14,6 @@ #include "bolt/Core/BinaryBasicBlock.h" #include "bolt/Passes/DataflowInfoManager.h" #include "bolt/Passes/FrameAnalysis.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCInstPrinter.h" #include #include diff --git a/bolt/lib/Profile/CMakeLists.txt b/bolt/lib/Profile/CMakeLists.txt index 3a31a9cc191971..045ac47edb950b 100644 --- a/bolt/lib/Profile/CMakeLists.txt +++ b/bolt/lib/Profile/CMakeLists.txt @@ -3,7 +3,6 @@ add_llvm_library(LLVMBOLTProfile DataAggregator.cpp DataReader.cpp Heatmap.cpp - ProfileReaderBase.cpp StaleProfileMatching.cpp YAMLProfileReader.cpp YAMLProfileWriter.cpp diff --git a/bolt/lib/Profile/DataReader.cpp b/bolt/lib/Profile/DataReader.cpp index aa21eb121ad652..67f357fe4d3f0c 100644 --- a/bolt/lib/Profile/DataReader.cpp +++ b/bolt/lib/Profile/DataReader.cpp @@ -18,7 +18,6 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Errc.h" -#include #undef DEBUG_TYPE #define DEBUG_TYPE "bolt-prof" diff --git a/bolt/lib/Profile/Heatmap.cpp b/bolt/lib/Profile/Heatmap.cpp index 13541f6f6a4b64..210a5cc98c1041 100644 --- a/bolt/lib/Profile/Heatmap.cpp +++ b/bolt/lib/Profile/Heatmap.cpp @@ -10,7 +10,6 @@ #include "bolt/Utils/CommandLineOpts.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" diff --git a/bolt/lib/Profile/ProfileReaderBase.cpp b/bolt/lib/Profile/ProfileReaderBase.cpp deleted file mode 100644 index ee6166b1da369e..00000000000000 --- a/bolt/lib/Profile/ProfileReaderBase.cpp +++ /dev/null @@ -1,23 +0,0 @@ -//===- bolt/Profile/ProfileReaderBase.cpp ---------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Interface to be implemented by all profile readers. -// -//===----------------------------------------------------------------------===// - -#include "bolt/Profile/ProfileReaderBase.h" - -namespace llvm { -namespace bolt { - -bool ProfileReaderBase::mayHaveProfileData(const BinaryFunction &BF) { - return true; -} - -} // namespace bolt -} // namespace llvm diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 601a2105fc264f..feeba89a40dc4d 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -14,7 +14,6 @@ #include "bolt/Core/DynoStats.h" #include "bolt/Core/ParallelUtilities.h" #include "bolt/Rewrite/RewriteInstance.h" -#include "bolt/Utils/Utils.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -1685,7 +1684,7 @@ namespace { std::unique_ptr createDwarfOnlyBC(const object::ObjectFile &File) { return cantFail(BinaryContext::createBinaryContext( - &File, false, + File.makeTriple(), File.getFileName(), nullptr, false, DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore, nullptr, "", WithColor::defaultErrorHandler, WithColor::defaultWarningHandler), diff --git a/bolt/lib/Rewrite/JITLinkLinker.cpp b/bolt/lib/Rewrite/JITLinkLinker.cpp index 66e129bf1d05db..be8f9dd03467e1 100644 --- a/bolt/lib/Rewrite/JITLinkLinker.cpp +++ b/bolt/lib/Rewrite/JITLinkLinker.cpp @@ -5,9 +5,11 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// + #include "bolt/Rewrite/JITLinkLinker.h" +#include "bolt/Core/BinaryContext.h" #include "bolt/Core/BinaryData.h" -#include "bolt/Rewrite/RewriteInstance.h" +#include "bolt/Core/BinarySection.h" #include "llvm/ExecutionEngine/JITLink/ELF_riscv.h" #include "llvm/ExecutionEngine/JITLink/JITLink.h" #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" diff --git a/bolt/lib/Rewrite/MachORewriteInstance.cpp b/bolt/lib/Rewrite/MachORewriteInstance.cpp index 0970a0507ebe88..172cb640bf911a 100644 --- a/bolt/lib/Rewrite/MachORewriteInstance.cpp +++ b/bolt/lib/Rewrite/MachORewriteInstance.cpp @@ -18,6 +18,7 @@ #include "bolt/Rewrite/BinaryPassManager.h" #include "bolt/Rewrite/ExecutableFileMemoryManager.h" #include "bolt/Rewrite/JITLinkLinker.h" +#include "bolt/Rewrite/RewriteInstance.h" #include "bolt/RuntimeLibs/InstrumentationRuntimeLibrary.h" #include "bolt/Utils/Utils.h" #include "llvm/MC/MCObjectStreamer.h" @@ -54,37 +55,6 @@ extern cl::opt Verbosity; namespace llvm { namespace bolt { -extern MCPlusBuilder *createX86MCPlusBuilder(const MCInstrAnalysis *, - const MCInstrInfo *, - const MCRegisterInfo *, - const MCSubtargetInfo *); -extern MCPlusBuilder *createAArch64MCPlusBuilder(const MCInstrAnalysis *, - const MCInstrInfo *, - const MCRegisterInfo *, - const MCSubtargetInfo *); - -namespace { - -MCPlusBuilder *createMCPlusBuilder(const Triple::ArchType Arch, - const MCInstrAnalysis *Analysis, - const MCInstrInfo *Info, - const MCRegisterInfo *RegInfo, - const MCSubtargetInfo *STI) { -#ifdef X86_AVAILABLE - if (Arch == Triple::x86_64) - return createX86MCPlusBuilder(Analysis, Info, RegInfo, STI); -#endif - -#ifdef AARCH64_AVAILABLE - if (Arch == Triple::aarch64) - return createAArch64MCPlusBuilder(Analysis, Info, RegInfo, STI); -#endif - - llvm_unreachable("architecture unsupported by MCPlusBuilder"); -} - -} // anonymous namespace - #define DEBUG_TYPE "bolt" Expected> @@ -103,7 +73,8 @@ MachORewriteInstance::MachORewriteInstance(object::MachOObjectFile *InputFile, : InputFile(InputFile), ToolPath(ToolPath) { ErrorAsOutParameter EAO(&Err); auto BCOrErr = BinaryContext::createBinaryContext( - InputFile, /* IsPIC */ true, DWARFContext::create(*InputFile), + InputFile->makeTriple(), InputFile->getFileName(), nullptr, + /* IsPIC */ true, DWARFContext::create(*InputFile), {llvm::outs(), llvm::errs()}); if (Error E = BCOrErr.takeError()) { Err = std::move(E); diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 2ead51ff6a1286..0c8ee0d417233b 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -84,6 +84,7 @@ extern cl::opt JumpTables; extern cl::opt KeepNops; extern cl::list ReorderData; extern cl::opt ReorderFunctions; +extern cl::opt TerminalTrap; extern cl::opt TimeBuild; cl::opt AllowStripped("allow-stripped", @@ -267,6 +268,10 @@ namespace bolt { extern const char *BoltRevision; +// Weird location for createMCPlusBuilder, but this is here to avoid a +// cyclic dependency of libCore (its natural place) and libTarget. libRewrite +// can depend on libTarget, but not libCore. Since libRewrite is the only +// user of this function, we define it here. MCPlusBuilder *createMCPlusBuilder(const Triple::ArchType Arch, const MCInstrAnalysis *Analysis, const MCInstrInfo *Info, @@ -344,8 +349,21 @@ RewriteInstance::RewriteInstance(ELFObjectFileBase *File, const int Argc, Stderr.SetUnbuffered(); LLVM_DEBUG(dbgs().SetUnbuffered()); + // Read RISCV subtarget features from input file + std::unique_ptr Features; + Triple TheTriple = File->makeTriple(); + if (TheTriple.getArch() == llvm::Triple::riscv64) { + Expected FeaturesOrErr = File->getFeatures(); + if (auto E = FeaturesOrErr.takeError()) { + Err = std::move(E); + return; + } else { + Features.reset(new SubtargetFeatures(*FeaturesOrErr)); + } + } + auto BCOrErr = BinaryContext::createBinaryContext( - File, IsPIC, + TheTriple, File->getFileName(), Features.get(), IsPIC, DWARFContext::create(*File, DWARFContext::ProcessDebugRelocations::Ignore, nullptr, opts::DWPPathName, WithColor::defaultErrorHandler, @@ -2033,8 +2051,14 @@ void RewriteInstance::adjustCommandLineOptions() { if (opts::Lite) BC->outs() << "BOLT-INFO: enabling lite mode\n"; - if (BC->IsLinuxKernel && !opts::KeepNops.getNumOccurrences()) - opts::KeepNops = true; + if (BC->IsLinuxKernel) { + if (!opts::KeepNops.getNumOccurrences()) + opts::KeepNops = true; + + // Linux kernel may resume execution after a trap instruction in some cases. + if (!opts::TerminalTrap.getNumOccurrences()) + opts::TerminalTrap = false; + } } namespace { diff --git a/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp index b6fc49d3f5d671..d114d70f2d3766 100644 --- a/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/HugifyRuntimeLibrary.cpp @@ -11,10 +11,9 @@ //===----------------------------------------------------------------------===// #include "bolt/RuntimeLibs/HugifyRuntimeLibrary.h" -#include "bolt/Core/BinaryFunction.h" +#include "bolt/Core/BinaryContext.h" #include "bolt/Core/Linker.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/Support/Alignment.h" #include "llvm/Support/CommandLine.h" using namespace llvm; diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp index ab9623d5c51b28..74f2f0aae91e66 100644 --- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp +++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp @@ -16,10 +16,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/raw_ostream.h" #define DEBUG_TYPE "mcplus" diff --git a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp index 15f95f82177765..8b1894953f3757 100644 --- a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp +++ b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp @@ -211,13 +211,6 @@ class X86MCPlusBuilder : public MCPlusBuilder { return false; } - // FIXME: For compatibility with old LLVM only! - bool isTerminator(const MCInst &Inst) const override { - unsigned Opcode = Inst.getOpcode(); - return Info->get(Opcode).isTerminator() || X86::isUD1(Opcode) || - X86::isUD2(Opcode); - } - bool isIndirectCall(const MCInst &Inst) const override { return isCall(Inst) && ((getMemoryOperandNo(Inst) != -1) || Inst.getOperand(0).isReg()); diff --git a/bolt/test/X86/linux-bug-table.s b/bolt/test/X86/linux-bug-table.s index f688a60c977191..63f70a0b35d9fe 100644 --- a/bolt/test/X86/linux-bug-table.s +++ b/bolt/test/X86/linux-bug-table.s @@ -40,6 +40,10 @@ _start: # CHECK-REOPT-SAME: BugEntry: 2 ret +## The return instruction is reachable only via preceding ud2. Test that it is +## treated as a reachable instruction in the Linux kernel mode. + +# CHECK-REOPT-NEXT: ret .size _start, .-_start diff --git a/bolt/tools/bat-dump/bat-dump.cpp b/bolt/tools/bat-dump/bat-dump.cpp index 2e9b26cc137a86..709eb076bca2da 100644 --- a/bolt/tools/bat-dump/bat-dump.cpp +++ b/bolt/tools/bat-dump/bat-dump.cpp @@ -1,9 +1,16 @@ +//===- bolt/tools/bat-dump/bat-dump.cpp - BAT dumper utility --------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #include "bolt/Profile/BoltAddressTranslation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/Error.h" @@ -18,7 +25,6 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Program.h" #include "llvm/Support/raw_ostream.h" -#include #include #include #include @@ -27,7 +33,6 @@ #include #include #include -#include using namespace llvm; using namespace bolt; diff --git a/bolt/tools/heatmap/heatmap.cpp b/bolt/tools/heatmap/heatmap.cpp index 9b190dd288b279..3bb9f2ce7491db 100644 --- a/bolt/tools/heatmap/heatmap.cpp +++ b/bolt/tools/heatmap/heatmap.cpp @@ -1,4 +1,11 @@ -#include "bolt/Profile/DataAggregator.h" +//===- bolt/tools/heatmap/heatmap.cpp - Profile heatmap visualization tool ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #include "bolt/Rewrite/RewriteInstance.h" #include "bolt/Utils/CommandLineOpts.h" #include "llvm/MC/TargetRegistry.h" @@ -6,7 +13,8 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" -#include "llvm/Support/Path.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Program.h" #include "llvm/Support/TargetSelect.h" using namespace llvm; diff --git a/bolt/unittests/Core/BinaryContext.cpp b/bolt/unittests/Core/BinaryContext.cpp index 08619eccdd75ab..cfec72a34a59f2 100644 --- a/bolt/unittests/Core/BinaryContext.cpp +++ b/bolt/unittests/Core/BinaryContext.cpp @@ -1,7 +1,14 @@ +//===- bolt/unittest/Core/BinaryContext.cpp -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #include "bolt/Core/BinaryContext.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" -#include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/TargetSelect.h" #include "gtest/gtest.h" @@ -40,8 +47,8 @@ struct BinaryContextTester : public testing::TestWithParam { void initializeBOLT() { BC = cantFail(BinaryContext::createBinaryContext( - ObjFile.get(), true, DWARFContext::create(*ObjFile.get()), - {llvm::outs(), llvm::errs()})); + ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true, + DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()})); ASSERT_FALSE(!BC); } diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp index daf9f392b82281..62f3aaab4a725c 100644 --- a/bolt/unittests/Core/MCPlusBuilder.cpp +++ b/bolt/unittests/Core/MCPlusBuilder.cpp @@ -1,3 +1,11 @@ +//===- bolt/unittest/Core/MCPlusBuilder.cpp -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #ifdef AARCH64_AVAILABLE #include "AArch64Subtarget.h" #endif // AARCH64_AVAILABLE @@ -11,7 +19,6 @@ #include "bolt/Rewrite/RewriteInstance.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" -#include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/TargetSelect.h" #include "gtest/gtest.h" @@ -50,8 +57,8 @@ struct MCPlusBuilderTester : public testing::TestWithParam { void initializeBolt() { BC = cantFail(BinaryContext::createBinaryContext( - ObjFile.get(), true, DWARFContext::create(*ObjFile.get()), - {llvm::outs(), llvm::errs()})); + ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true, + DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()})); ASSERT_FALSE(!BC); BC->initializeTarget(std::unique_ptr( createMCPlusBuilder(GetParam(), BC->MIA.get(), BC->MII.get(), diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 5728c9970fb65d..dd772d69202548 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -17,6 +17,7 @@ add_clang_library(clangTidyReadabilityModule DeleteNullPointerCheck.cpp DuplicateIncludeCheck.cpp ElseAfterReturnCheck.cpp + EnumInitialValueCheck.cpp FunctionCognitiveComplexityCheck.cpp FunctionSizeCheck.cpp IdentifierLengthCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp new file mode 100644 index 00000000000000..8f2841c32259a2 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp @@ -0,0 +1,200 @@ +//===--- EnumInitialValueCheck.cpp - clang-tidy ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "EnumInitialValueCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/AST/Decl.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +static bool isNoneEnumeratorsInitialized(const EnumDecl &Node) { + return llvm::all_of(Node.enumerators(), [](const EnumConstantDecl *ECD) { + return ECD->getInitExpr() == nullptr; + }); +} + +static bool isOnlyFirstEnumeratorInitialized(const EnumDecl &Node) { + bool IsFirst = true; + for (const EnumConstantDecl *ECD : Node.enumerators()) { + if ((IsFirst && ECD->getInitExpr() == nullptr) || + (!IsFirst && ECD->getInitExpr() != nullptr)) + return false; + IsFirst = false; + } + return !IsFirst; +} + +static bool areAllEnumeratorsInitialized(const EnumDecl &Node) { + return llvm::all_of(Node.enumerators(), [](const EnumConstantDecl *ECD) { + return ECD->getInitExpr() != nullptr; + }); +} + +/// Check if \p Enumerator is initialized with a (potentially negated) \c +/// IntegerLiteral. +static bool isInitializedByLiteral(const EnumConstantDecl *Enumerator) { + const Expr *const Init = Enumerator->getInitExpr(); + if (!Init) + return false; + return Init->isIntegerConstantExpr(Enumerator->getASTContext()); +} + +static void cleanInitialValue(DiagnosticBuilder &Diag, + const EnumConstantDecl *ECD, + const SourceManager &SM, + const LangOptions &LangOpts) { + const SourceRange InitExprRange = ECD->getInitExpr()->getSourceRange(); + if (InitExprRange.isInvalid() || InitExprRange.getBegin().isMacroID() || + InitExprRange.getEnd().isMacroID()) + return; + std::optional EqualToken = utils::lexer::findNextTokenSkippingComments( + ECD->getLocation(), SM, LangOpts); + if (!EqualToken.has_value() || + EqualToken.value().getKind() != tok::TokenKind::equal) + return; + const SourceLocation EqualLoc{EqualToken->getLocation()}; + if (EqualLoc.isInvalid() || EqualLoc.isMacroID()) + return; + Diag << FixItHint::CreateRemoval(EqualLoc) + << FixItHint::CreateRemoval(InitExprRange); + return; +} + +namespace { + +AST_MATCHER(EnumDecl, isMacro) { + SourceLocation Loc = Node.getBeginLoc(); + return Loc.isMacroID(); +} + +AST_MATCHER(EnumDecl, hasConsistentInitialValues) { + return isNoneEnumeratorsInitialized(Node) || + isOnlyFirstEnumeratorInitialized(Node) || + areAllEnumeratorsInitialized(Node); +} + +AST_MATCHER(EnumDecl, hasZeroInitialValueForFirstEnumerator) { + const EnumDecl::enumerator_range Enumerators = Node.enumerators(); + if (Enumerators.empty()) + return false; + const EnumConstantDecl *ECD = *Enumerators.begin(); + return isOnlyFirstEnumeratorInitialized(Node) && + isInitializedByLiteral(ECD) && ECD->getInitVal().isZero(); +} + +/// Excludes bitfields because enumerators initialized with the result of a +/// bitwise operator on enumeration values or any other expr that is not a +/// potentially negative integer literal. +/// Enumerations where it is not directly clear if they are used with +/// bitmask, evident when enumerators are only initialized with (potentially +/// negative) integer literals, are ignored. This is also the case when all +/// enumerators are powers of two (e.g., 0, 1, 2). +AST_MATCHER(EnumDecl, hasSequentialInitialValues) { + const EnumDecl::enumerator_range Enumerators = Node.enumerators(); + if (Enumerators.empty()) + return false; + const EnumConstantDecl *const FirstEnumerator = *Node.enumerator_begin(); + llvm::APSInt PrevValue = FirstEnumerator->getInitVal(); + if (!isInitializedByLiteral(FirstEnumerator)) + return false; + bool AllEnumeratorsArePowersOfTwo = true; + for (const EnumConstantDecl *Enumerator : llvm::drop_begin(Enumerators)) { + const llvm::APSInt NewValue = Enumerator->getInitVal(); + if (NewValue != ++PrevValue) + return false; + if (!isInitializedByLiteral(Enumerator)) + return false; + PrevValue = NewValue; + AllEnumeratorsArePowersOfTwo &= NewValue.isPowerOf2(); + } + return !AllEnumeratorsArePowersOfTwo; +} + +} // namespace + +EnumInitialValueCheck::EnumInitialValueCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + AllowExplicitZeroFirstInitialValue( + Options.get("AllowExplicitZeroFirstInitialValue", true)), + AllowExplicitSequentialInitialValues( + Options.get("AllowExplicitSequentialInitialValues", true)) {} + +void EnumInitialValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "AllowExplicitZeroFirstInitialValue", + AllowExplicitZeroFirstInitialValue); + Options.store(Opts, "AllowExplicitSequentialInitialValues", + AllowExplicitSequentialInitialValues); +} + +void EnumInitialValueCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + enumDecl(unless(isMacro()), unless(hasConsistentInitialValues())) + .bind("inconsistent"), + this); + if (!AllowExplicitZeroFirstInitialValue) + Finder->addMatcher( + enumDecl(hasZeroInitialValueForFirstEnumerator()).bind("zero_first"), + this); + if (!AllowExplicitSequentialInitialValues) + Finder->addMatcher(enumDecl(unless(isMacro()), hasSequentialInitialValues()) + .bind("sequential"), + this); +} + +void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *Enum = Result.Nodes.getNodeAs("inconsistent")) { + DiagnosticBuilder Diag = + diag(Enum->getBeginLoc(), + "inital values in enum %0 are not consistent, consider explicit " + "initialization of all, none or only the first enumerator") + << Enum; + for (const EnumConstantDecl *ECD : Enum->enumerators()) + if (ECD->getInitExpr() == nullptr) { + const SourceLocation EndLoc = Lexer::getLocForEndOfToken( + ECD->getLocation(), 0, *Result.SourceManager, getLangOpts()); + if (EndLoc.isMacroID()) + continue; + llvm::SmallString<8> Str{" = "}; + ECD->getInitVal().toString(Str); + Diag << FixItHint::CreateInsertion(EndLoc, Str); + } + return; + } + + if (const auto *Enum = Result.Nodes.getNodeAs("zero_first")) { + const EnumConstantDecl *ECD = *Enum->enumerator_begin(); + const SourceLocation Loc = ECD->getLocation(); + if (Loc.isInvalid() || Loc.isMacroID()) + return; + DiagnosticBuilder Diag = diag(Loc, "zero initial value for the first " + "enumerator in %0 can be disregarded") + << Enum; + cleanInitialValue(Diag, ECD, *Result.SourceManager, getLangOpts()); + return; + } + if (const auto *Enum = Result.Nodes.getNodeAs("sequential")) { + DiagnosticBuilder Diag = + diag(Enum->getBeginLoc(), + "sequential initial value in %0 can be ignored") + << Enum; + for (const EnumConstantDecl *ECD : llvm::drop_begin(Enum->enumerators())) + cleanInitialValue(Diag, ECD, *Result.SourceManager, getLangOpts()); + return; + } +} + +} // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.h b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.h new file mode 100644 index 00000000000000..66087e4ee170da --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.h @@ -0,0 +1,38 @@ +//===--- EnumInitialValueCheck.h - clang-tidy -------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ENUMINITIALVALUECHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ENUMINITIALVALUECHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Enforces consistent style for enumerators' initialization, covering three +/// styles: none, first only, or all initialized explicitly. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability/enum-initial-value.html +class EnumInitialValueCheck : public ClangTidyCheck { +public: + EnumInitialValueCheck(StringRef Name, ClangTidyContext *Context); + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + std::optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } + +private: + const bool AllowExplicitZeroFirstInitialValue; + const bool AllowExplicitSequentialInitialValues; +}; + +} // namespace clang::tidy::readability + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ENUMINITIALVALUECHECK_H diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index bca2c425111f6c..376b84683df74e 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -22,6 +22,7 @@ #include "DeleteNullPointerCheck.h" #include "DuplicateIncludeCheck.h" #include "ElseAfterReturnCheck.h" +#include "EnumInitialValueCheck.h" #include "FunctionCognitiveComplexityCheck.h" #include "FunctionSizeCheck.h" #include "IdentifierLengthCheck.h" @@ -92,6 +93,8 @@ class ReadabilityModule : public ClangTidyModule { "readability-duplicate-include"); CheckFactories.registerCheck( "readability-else-after-return"); + CheckFactories.registerCheck( + "readability-enum-initial-value"); CheckFactories.registerCheck( "readability-function-cognitive-complexity"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp b/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp index b6d9c50d0b109c..a44720c47eca2d 100644 --- a/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp +++ b/clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp @@ -108,7 +108,7 @@ int compareHeaders(StringRef LHS, StringRef RHS, IncludeSorter::IncludeStyle Style) { if (Style == IncludeSorter::IncludeStyle::IS_Google_ObjC) { const std::pair &Mismatch = - std::mismatch(LHS.begin(), LHS.end(), RHS.begin()); + std::mismatch(LHS.begin(), LHS.end(), RHS.begin(), RHS.end()); if ((Mismatch.first != LHS.end()) && (Mismatch.second != RHS.end())) { if ((*Mismatch.first == '.') && (*Mismatch.second == '+')) { return -1; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 78b09d23d4427f..309b844615a121 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -123,6 +123,12 @@ New checks Finds initializer lists for aggregate types that could be written as designated initializers instead. +- New :doc:`readability-enum-initial-value + ` check. + + Enforces consistent style for enumerators' initialization, covering three + styles: none, first only, or all initialized explicitly. + - New :doc:`readability-use-std-min-max ` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 79e81dd174e4f3..188a42bfddd383 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -352,6 +352,7 @@ Clang-Tidy Checks :doc:`readability-delete-null-pointer `, "Yes" :doc:`readability-duplicate-include `, "Yes" :doc:`readability-else-after-return `, "Yes" + :doc:`readability-enum-initial-value `, "Yes" :doc:`readability-function-cognitive-complexity `, :doc:`readability-function-size `, :doc:`readability-identifier-length `, diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst new file mode 100644 index 00000000000000..660efc1eaff3e5 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/enum-initial-value.rst @@ -0,0 +1,75 @@ +.. title:: clang-tidy - readability-enum-initial-value + +readability-enum-initial-value +============================== + +Enforces consistent style for enumerators' initialization, covering three +styles: none, first only, or all initialized explicitly. + +When adding new enumerations, inconsistent initial value will cause potential +enumeration value conflicts. + +In an enumeration, the following three cases are accepted. +1. none of enumerators are explicit initialized. +2. the first enumerator is explicit initialized. +3. all of enumerators are explicit initialized. + +.. code-block:: c++ + + // valid, none of enumerators are initialized. + enum A { + e0, + e1, + e2, + }; + + // valid, the first enumerator is initialized. + enum A { + e0 = 0, + e1, + e2, + }; + + // valid, all of enumerators are initialized. + enum A { + e0 = 0, + e1 = 1, + e2 = 2, + }; + + // invalid, e1 is not explicit initialized. + enum A { + e0 = 0, + e1, + e2 = 2, + }; + +Options +------- + +.. option:: AllowExplicitZeroFirstInitialValue + + If set to `false`, the first enumerator must not be explicitly initialized. + See examples below. Default is `true`. + + .. code-block:: c++ + + enum A { + e0 = 0, // not allowed if AllowExplicitZeroFirstInitialValue is false + e1, + e2, + }; + + +.. option:: AllowExplicitSequentialInitialValues + + If set to `false`, sequential initializations are not allowed. + See examples below. Default is `true`. + + .. code-block:: c++ + + enum A { + e0 = 1, // not allowed if AllowExplicitSequentialInitialValues is false + e1 = 2, + e2 = 3, + }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c new file mode 100644 index 00000000000000..c66288cbe3e957 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c @@ -0,0 +1,80 @@ +// RUN: %check_clang_tidy %s readability-enum-initial-value %t +// RUN: %check_clang_tidy -check-suffix=ENABLE %s readability-enum-initial-value %t -- \ +// RUN: -config='{CheckOptions: { \ +// RUN: readability-enum-initial-value.AllowExplicitZeroFirstInitialValue: false, \ +// RUN: readability-enum-initial-value.AllowExplicitSequentialInitialValues: false, \ +// RUN: }}' + +enum EError { + // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: inital values in enum 'EError' are not consistent + // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: inital values in enum 'EError' are not consistent + EError_a = 1, + EError_b, + // CHECK-FIXES: EError_b = 2, + EError_c = 3, +}; + +enum ENone { + ENone_a, + ENone_b, + EENone_c, +}; + +enum EFirst { + EFirst_a = 1, + EFirst_b, + EFirst_c, +}; + +enum EAll { + EAll_a = 1, + EAll_b = 2, + EAll_c = 4, +}; + +#define ENUMERATOR_1 EMacro1_b +enum EMacro1 { + // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: inital values in enum 'EMacro1' are not consistent + // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: inital values in enum 'EMacro1' are not consistent + EMacro1_a = 1, + ENUMERATOR_1, + // CHECK-FIXES: ENUMERATOR_1 = 2, + EMacro1_c = 3, +}; + + +#define ENUMERATOR_2 EMacro2_b = 2 +enum EMacro2 { + // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: inital values in enum 'EMacro2' are not consistent + // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: inital values in enum 'EMacro2' are not consistent + EMacro2_a = 1, + ENUMERATOR_2, + EMacro2_c, + // CHECK-FIXES: EMacro2_c = 3, +}; + +enum EnumZeroFirstInitialValue { + EnumZeroFirstInitialValue_0 = 0, + // CHECK-MESSAGES-ENABLE: :[[@LINE-1]]:3: warning: zero initial value for the first enumerator in 'EnumZeroFirstInitialValue' can be disregarded + // CHECK-FIXES-ENABLE: EnumZeroFirstInitialValue_0 , + EnumZeroFirstInitialValue_1, + EnumZeroFirstInitialValue_2, +}; + +enum EnumZeroFirstInitialValueWithComment { + EnumZeroFirstInitialValueWithComment_0 = /* == */ 0, + // CHECK-MESSAGES-ENABLE: :[[@LINE-1]]:3: warning: zero initial value for the first enumerator in 'EnumZeroFirstInitialValueWithComment' can be disregarded + // CHECK-FIXES-ENABLE: EnumZeroFirstInitialValueWithComment_0 /* == */ , + EnumZeroFirstInitialValueWithComment_1, + EnumZeroFirstInitialValueWithComment_2, +}; + +enum EnumSequentialInitialValue { + // CHECK-MESSAGES-ENABLE: :[[@LINE-1]]:1: warning: sequential initial value in 'EnumSequentialInitialValue' can be ignored + EnumSequentialInitialValue_0 = 2, + // CHECK-FIXES-ENABLE: EnumSequentialInitialValue_0 = 2, + EnumSequentialInitialValue_1 = 3, + // CHECK-FIXES-ENABLE: EnumSequentialInitialValue_1 , + EnumSequentialInitialValue_2 = 4, + // CHECK-FIXES-ENABLE: EnumSequentialInitialValue_2 , +}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp new file mode 100644 index 00000000000000..3c4ba970372a07 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.cpp @@ -0,0 +1,27 @@ +// RUN: %check_clang_tidy %s readability-enum-initial-value %t + +enum class EError { + // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: inital values in enum 'EError' are not consistent + EError_a = 1, + EError_b, + // CHECK-FIXES: EError_b = 2, + EError_c = 3, +}; + +enum class ENone { + ENone_a, + ENone_b, + EENone_c, +}; + +enum class EFirst { + EFirst_a = 1, + EFirst_b, + EFirst_c, +}; + +enum class EAll { + EAll_a = 1, + EAll_b = 2, + EAll_c = 3, +}; diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp index d0efc5ca763753..57d930b26e64c0 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp @@ -25,7 +25,7 @@ // RUN: not clang-tidy -checks='-*,modernize-use-override' %T/diagnostics/input.cpp -- -DCOMPILATION_ERROR 2>&1 | FileCheck -check-prefix=CHECK6 -implicit-check-not='{{warning:|error:}}' %s // RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE -std=c++20 | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s // RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined,clang-diagnostic-literal-conversion' %s -- -DMACRO_FROM_COMMAND_LINE -std=c++20 -Wno-macro-redefined | FileCheck --check-prefix=CHECK7 -implicit-check-not='{{warning:|error:}}' %s -// RUN: not clang-tidy -checks='-*,modernize-use-override' %s -- -std=c++20 -DPR64602 | FileCheck -check-prefix=CHECK8 -implicit-check-not='{{warning:|error:}}' %s +// RUN: clang-tidy -checks='-*,modernize-use-override' %s -- -std=c++20 -DPR64602 // CHECK1: error: no input files [clang-diagnostic-error] // CHECK1: error: no such file or directory: '{{.*}}nonexistent.cpp' [clang-diagnostic-error] @@ -68,6 +68,4 @@ auto S<>::foo(auto) { return 1; } -// CHECK8: error: conflicting types for 'foo' [clang-diagnostic-error] -// CHECK8: note: previous declaration is here #endif diff --git a/clang/cmake/caches/CrossWinToARMLinux.cmake b/clang/cmake/caches/CrossWinToARMLinux.cmake index 2a0953af53fadd..736a54ece550c6 100644 --- a/clang/cmake/caches/CrossWinToARMLinux.cmake +++ b/clang/cmake/caches/CrossWinToARMLinux.cmake @@ -29,6 +29,11 @@ # cmake --build . --target check-cxxabi- # cmake --build . --target check-unwind- # cmake --build . --target check-cxx- +# (another way to execute the tests) +# python bin/llvm-lit.py -v --threads=32 runtimes/runtimes-bins/libunwind/test 2>&1 | tee libunwind-tests.log +# python bin/llvm-lit.py -v --threads=32 runtimes/runtimes--bins/libcxxabi/test 2>&1 | tee libcxxabi-tests.log +# python bin/llvm-lit.py -v --threads=32 runtimes/runtimes--bins/libcxx/test 2>&1 | tee libcxx-tests.log + # LLVM_PROJECT_DIR is the path to the llvm-project directory. # The right way to compute it would probably be to use "${CMAKE_SOURCE_DIR}/../", @@ -42,9 +47,6 @@ if (NOT DEFINED DEFAULT_SYSROOT) message(WARNING "DEFAULT_SYSROOT must be specified for the cross toolchain build.") endif() -if (NOT DEFINED LLVM_TARGETS_TO_BUILD) - set(LLVM_TARGETS_TO_BUILD "ARM" CACHE STRING "") -endif() if (NOT DEFINED LLVM_ENABLE_ASSERTIONS) set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") endif() @@ -56,7 +58,7 @@ if (NOT DEFINED LLVM_ENABLE_RUNTIMES) endif() if (NOT DEFINED TOOLCHAIN_TARGET_TRIPLE) - set(TOOLCHAIN_TARGET_TRIPLE "armv7-unknown-linux-gnueabihf") + set(TOOLCHAIN_TARGET_TRIPLE "aarch64-unknown-linux-gnu") else() #NOTE: we must normalize specified target triple to a fully specified triple, # including the vendor part. It is necessary to synchronize the runtime library @@ -74,24 +76,38 @@ else() string(REPLACE ";" "-" TOOLCHAIN_TARGET_TRIPLE "${TOOLCHAIN_TARGET_TRIPLE}") endif() +message(STATUS "Toolchain target triple: ${TOOLCHAIN_TARGET_TRIPLE}") + +if (NOT DEFINED LLVM_TARGETS_TO_BUILD) + if ("${TOOLCHAIN_TARGET_TRIPLE}" MATCHES "^(armv|arm32)+") + set(LLVM_TARGETS_TO_BUILD "ARM" CACHE STRING "") + endif() + if ("${TOOLCHAIN_TARGET_TRIPLE}" MATCHES "^(aarch64|arm64)+") + set(LLVM_TARGETS_TO_BUILD "AArch64" CACHE STRING "") + endif() +endif() + +message(STATUS "Toolchain target to build: ${LLVM_TARGETS_TO_BUILD}") + if (NOT DEFINED CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") endif() -message(STATUS "Toolchain target triple: ${TOOLCHAIN_TARGET_TRIPLE}") - set(CMAKE_CROSSCOMPILING ON CACHE BOOL "") set(CMAKE_CL_SHOWINCLUDES_PREFIX "Note: including file: " CACHE STRING "") # Required if COMPILER_RT_DEFAULT_TARGET_ONLY is ON set(CMAKE_C_COMPILER_TARGET "${TOOLCHAIN_TARGET_TRIPLE}" CACHE STRING "") set(CMAKE_CXX_COMPILER_TARGET "${TOOLCHAIN_TARGET_TRIPLE}" CACHE STRING "") -set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") set(LLVM_DEFAULT_TARGET_TRIPLE "${TOOLCHAIN_TARGET_TRIPLE}" CACHE STRING "") set(LLVM_TARGET_ARCH "${TOOLCHAIN_TARGET_TRIPLE}" CACHE STRING "") set(LLVM_LIT_ARGS "-vv ${LLVM_LIT_ARGS}" CACHE STRING "" FORCE) +set(CLANG_DEFAULT_CXX_STDLIB "libc++" CACHE STRING "") set(CLANG_DEFAULT_LINKER "lld" CACHE STRING "") +set(CLANG_DEFAULT_OBJCOPY "llvm-objcopy" CACHE STRING "") +set(CLANG_DEFAULT_RTLIB "compiler-rt" CACHE STRING "") +set(CLANG_DEFAULT_UNWINDLIB "libunwind" CACHE STRING "") if(WIN32) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded" CACHE STRING "") @@ -109,9 +125,10 @@ set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_SYSTEM_NAME set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_SYSROOT "${DEFAULT_SYSROOT}" CACHE STRING "") set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_INSTALL_RPATH "${RUNTIMES_INSTALL_RPATH}" CACHE STRING "") set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "") - +set(BUILTINS_${TOOLCHAIN_TARGET_TRIPLE}_LLVM_CMAKE_DIR "${LLVM_PROJECT_DIR}/llvm/cmake/modules" CACHE PATH "") set(LLVM_RUNTIME_TARGETS "${TOOLCHAIN_TARGET_TRIPLE}" CACHE STRING "") +set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LLVM_ENABLE_RUNTIMES "${LLVM_ENABLE_RUNTIMES}" CACHE STRING "") @@ -125,13 +142,16 @@ set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_SANITIZERS set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_PROFILE OFF CACHE BOOL "") -set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_CRT OFF CACHE BOOL "") +set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_CRT ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_BUILD_ORC OFF CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_DEFAULT_TARGET_ONLY ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_INCLUDE_TESTS ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_CAN_EXECUTE_TESTS ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") +set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_CXX_LIBRARY libcxx CACHE STRING "") +# Tell Clang to seach C++ headers alongside with the just-built binaries for the C++ compiler-rt tests. +set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_COMPILER_RT_TEST_COMPILER_CFLAGS "--stdlib=libc++" CACHE STRING "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") @@ -148,8 +168,10 @@ set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ABI_VERSION set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_CXX_ABI "libcxxabi" CACHE STRING "") #!!! set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS ON CACHE BOOL "") - +# Avoid searching for the python3 interpreter during the runtimes configuration for the cross builds. +# It starts searching the python3 package using the target's sysroot path, that usually is not compatible with the build host. find_package(Python3 COMPONENTS Interpreter) +set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_Python3_EXECUTABLE ${Python3_EXECUTABLE} CACHE PATH "") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBUNWIND_TEST_PARAMS_default "${RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_TEST_PARAMS}") set(RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_LIBCXXABI_TEST_PARAMS_default "${RUNTIMES_${TOOLCHAIN_TARGET_TRIPLE}_TEST_PARAMS}") diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 2ee36f24d7ce4b..39f7cded36edbf 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -3295,6 +3295,21 @@ the configuration (without a prefix: ``Auto``). +.. _BreakFunctionDefinitionParameters: + +**BreakFunctionDefinitionParameters** (``Boolean``) :versionbadge:`clang-format 19` :ref:`¶ ` + If ``true``, clang-format will always break before function definition + parameters. + + .. code-block:: c++ + + true: + void functionDefinition( + int A, int B) {} + + false: + void functionDefinition(int A, int B) {} + .. _BreakInheritanceList: **BreakInheritanceList** (``BreakInheritanceListStyle``) :versionbadge:`clang-format 7` :ref:`¶ ` diff --git a/clang/docs/HLSL/FunctionCalls.rst b/clang/docs/HLSL/FunctionCalls.rst index 7317de2163f897..6d65fe6e3fb20b 100644 --- a/clang/docs/HLSL/FunctionCalls.rst +++ b/clang/docs/HLSL/FunctionCalls.rst @@ -157,22 +157,23 @@ Clang Implementation of the changes in the prototype implementation are restoring Clang-3.7 code that was previously modified to its original state. -The implementation in clang depends on two new AST nodes and minor extensions to -Clang's existing support for Objective-C write-back arguments. The goal of this -design is to capture the semantic details of HLSL function calls in the AST, and -minimize the amount of magic that needs to occur during IR generation. - -The two new AST nodes are ``HLSLArrayTemporaryExpr`` and ``HLSLOutParamExpr``, -which respectively represent the temporaries used for passing arrays by value -and the temporaries created for function outputs. +The implementation in clang adds a new non-decaying array type, a new AST node +to represent output parameters, and minor extensions to Clang's existing support +for Objective-C write-back arguments. The goal of this design is to capture the +semantic details of HLSL function calls in the AST, and minimize the amount of +magic that needs to occur during IR generation. Array Temporaries ----------------- -The ``HLSLArrayTemporaryExpr`` represents temporary values for input -constant-sized array arguments. This applies for all constant-sized array -arguments regardless of whether or not the parameter is constant-sized or -unsized. +The new ``ArrayParameterType`` is a sub-class of ``ConstantArrayType`` +inheriting all the behaviors and methods of the parent except that it does not +decay to a pointer during overload resolution or template type deduction. + +An argument of ``ConstantArrayType`` can be implicitly converted to an +equivalent non-decayed ``ArrayParameterType`` if the underlying canonical +``ConstantArrayType`` is the same. This occurs during overload resolution +instead of array to pointer decay. .. code-block:: c++ @@ -193,7 +194,7 @@ In the example above, the following AST is generated for the call to CallExpr 'void' |-ImplicitCastExpr 'void (*)(float [4])' | `-DeclRefExpr 'void (float [4])' lvalue Function 'SizedArray' 'void (float [4])' - `-HLSLArrayTemporaryExpr 'float [4]' + `-ImplicitCastExpr 'float [4]' `-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]' In the example above, the following AST is generated for the call to @@ -204,7 +205,7 @@ In the example above, the following AST is generated for the call to CallExpr 'void' |-ImplicitCastExpr 'void (*)(float [])' | `-DeclRefExpr 'void (float [])' lvalue Function 'UnsizedArray' 'void (float [])' - `-HLSLArrayTemporaryExpr 'float [4]' + `-ImplicitCastExpr 'float [4]' `-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]' In both of these cases the argument expression is of known array size so we can @@ -236,7 +237,7 @@ An expected AST should be something like: CallExpr 'void' |-ImplicitCastExpr 'void (*)(float [])' | `-DeclRefExpr 'void (float [])' lvalue Function 'UnsizedArray' 'void (float [])' - `-HLSLArrayTemporaryExpr 'float [4]' + `-ImplicitCastExpr 'float [4]' `-DeclRefExpr 'float [4]' lvalue Var 'arr' 'float [4]' Out Parameter Temporaries diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c303eee7be7927..d5ce54e185600c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -322,6 +322,12 @@ Improvements to Clang's diagnostics - ``-Wmicrosoft``, ``-Wgnu``, or ``-pedantic`` is now required to diagnose C99 flexible array members in a union or alone in a struct. Fixes GH#84565. +- Clang now no longer diagnoses type definitions in ``offsetof`` in C23 mode. + Fixes #GH83658. + +- New ``-Wformat-signedness`` diagnostic that warn if the format string requires an + unsigned argument and the argument is signed and vice versa. + Improvements to Clang's time-trace ---------------------------------- @@ -372,6 +378,9 @@ Bug Fixes in This Version - Fixes an assertion failure on invalid code when trying to define member functions in lambdas. +- Fixed a regression in CTAD that a friend declaration that befriends itself may cause + incorrect constraint substitution. (#GH86769). + Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -474,6 +483,11 @@ Bug Fixes to C++ Support following the first `::` were ignored). - Fix an out-of-bounds crash when checking the validity of template partial specializations. (part of #GH86757). - Fix an issue caused by not handling invalid cases when substituting into the parameter mapping of a constraint. Fixes (#GH86757). +- Fixed a bug that prevented member function templates of class templates declared with a deduced return type + from being explicitly specialized for a given implicit instantiation of the class template. + +- Fix crash when inheriting from a cv-qualified type. Fixes: + (`#35603 `_) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 002f36ecbbaa3f..08f71051e6cbf3 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -260,6 +260,9 @@ class ASTContext : public RefCountedBase { ASTContext&> SubstTemplateTemplateParmPacks; + mutable llvm::ContextualFoldingSet + ArrayParameterTypes; + /// The set of nested name specifiers. /// /// This set is managed by the NestedNameSpecifier class. @@ -1367,6 +1370,10 @@ class ASTContext : public RefCountedBase { /// type to the decayed type. QualType getDecayedType(QualType Orig, QualType Decayed) const; + /// Return the uniqued reference to a specified array parameter type from the + /// original array type. + QualType getArrayParameterType(QualType Ty) const; + /// Return the uniqued reference to the atomic type for the specified /// type. QualType getAtomicType(QualType T) const; diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 47ed6d0d1db0df..858450926455c6 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -669,9 +669,8 @@ class alignas(8) Decl { /// Whether this declaration comes from another module unit. bool isInAnotherModuleUnit() const; - /// FIXME: Implement discarding declarations actually in global module - /// fragment. See [module.global.frag]p3,4 for details. - bool isDiscardedInGlobalModuleFragment() const { return false; } + /// Whether this declaration comes from explicit global module. + bool isFromExplicitGlobalModule() const; /// Check if we should skip checking ODRHash for declaration \param D. /// diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 6e153ebe024b42..2bfefeabc348be 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3163,23 +3163,12 @@ class CallExpr : public Expr { } }; -/// Extra data stored in some MemberExpr objects. -struct MemberExprNameQualifier { - /// The nested-name-specifier that qualifies the name, including - /// source-location information. - NestedNameSpecifierLoc QualifierLoc; - - /// The DeclAccessPair through which the MemberDecl was found due to - /// name qualifiers. - DeclAccessPair FoundDecl; -}; - /// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F. /// class MemberExpr final : public Expr, - private llvm::TrailingObjects { friend class ASTReader; friend class ASTStmtReader; @@ -3201,26 +3190,30 @@ class MemberExpr final /// MemberLoc - This is the location of the member name. SourceLocation MemberLoc; - size_t numTrailingObjects(OverloadToken) const { - return hasQualifierOrFoundDecl(); + size_t numTrailingObjects(OverloadToken) const { + return hasQualifier(); + } + + size_t numTrailingObjects(OverloadToken) const { + return hasFoundDecl(); } size_t numTrailingObjects(OverloadToken) const { return hasTemplateKWAndArgsInfo(); } - bool hasQualifierOrFoundDecl() const { - return MemberExprBits.HasQualifierOrFoundDecl; - } + bool hasFoundDecl() const { return MemberExprBits.HasFoundDecl; } bool hasTemplateKWAndArgsInfo() const { return MemberExprBits.HasTemplateKWAndArgsInfo; } MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc, - ValueDecl *MemberDecl, const DeclarationNameInfo &NameInfo, - QualType T, ExprValueKind VK, ExprObjectKind OK, - NonOdrUseReason NOUR); + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, + ValueDecl *MemberDecl, DeclAccessPair FoundDecl, + const DeclarationNameInfo &NameInfo, + const TemplateArgumentListInfo *TemplateArgs, QualType T, + ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR); MemberExpr(EmptyShell Empty) : Expr(MemberExprClass, Empty), Base(), MemberDecl() {} @@ -3264,24 +3257,24 @@ class MemberExpr final /// Retrieves the declaration found by lookup. DeclAccessPair getFoundDecl() const { - if (!hasQualifierOrFoundDecl()) + if (!hasFoundDecl()) return DeclAccessPair::make(getMemberDecl(), getMemberDecl()->getAccess()); - return getTrailingObjects()->FoundDecl; + return *getTrailingObjects(); } /// Determines whether this member expression actually had /// a C++ nested-name-specifier prior to the name of the member, e.g., /// x->Base::foo. - bool hasQualifier() const { return getQualifier() != nullptr; } + bool hasQualifier() const { return MemberExprBits.HasQualifier; } /// If the member name was qualified, retrieves the /// nested-name-specifier that precedes the member name, with source-location /// information. NestedNameSpecifierLoc getQualifierLoc() const { - if (!hasQualifierOrFoundDecl()) + if (!hasQualifier()) return NestedNameSpecifierLoc(); - return getTrailingObjects()->QualifierLoc; + return *getTrailingObjects(); } /// If the member name was qualified, retrieves the diff --git a/clang/include/clang/AST/FormatString.h b/clang/include/clang/AST/FormatString.h index e2232fb4a47153..a074dd23e2ad4c 100644 --- a/clang/include/clang/AST/FormatString.h +++ b/clang/include/clang/AST/FormatString.h @@ -284,6 +284,8 @@ class ArgType { /// The conversion specifier and the argument type are disallowed by the C /// standard, but are in practice harmless. For instance, "%p" and int*. NoMatchPedantic, + /// The conversion specifier and the argument type have different sign. + NoMatchSignedness, /// The conversion specifier and the argument type are compatible, but still /// seems likely to be an error. For instance, "%hd" and _Bool. NoMatchTypeConfusion, diff --git a/clang/include/clang/AST/OperationKinds.def b/clang/include/clang/AST/OperationKinds.def index ef05072800f11a..8788b8ff0ef0a4 100644 --- a/clang/include/clang/AST/OperationKinds.def +++ b/clang/include/clang/AST/OperationKinds.def @@ -364,6 +364,9 @@ CAST_OPERATION(IntToOCLSampler) // Truncate a vector type by dropping elements from the end (HLSL only). CAST_OPERATION(HLSLVectorTruncation) +// Non-decaying array RValue cast (HLSL only). +CAST_OPERATION(HLSLArrayRValue) + //===- Binary Operations -------------------------------------------------===// // Operators listed in order of precedence. // Note that additions to this should also update the StmtVisitor class, diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 4a1ff222ecadcd..8630317795a9ad 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -993,6 +993,12 @@ DEF_TRAVERSE_TYPE(ConstantArrayType, { TRY_TO(TraverseStmt(const_cast(T->getSizeExpr()))); }) +DEF_TRAVERSE_TYPE(ArrayParameterType, { + TRY_TO(TraverseType(T->getElementType())); + if (T->getSizeExpr()) + TRY_TO(TraverseStmt(const_cast(T->getSizeExpr()))); +}) + DEF_TRAVERSE_TYPE(IncompleteArrayType, { TRY_TO(TraverseType(T->getElementType())); }) @@ -1260,6 +1266,11 @@ DEF_TRAVERSE_TYPELOC(ConstantArrayType, { TRY_TO(TraverseArrayTypeLocHelper(TL)); }) +DEF_TRAVERSE_TYPELOC(ArrayParameterType, { + TRY_TO(TraverseTypeLoc(TL.getElementLoc())); + TRY_TO(TraverseArrayTypeLocHelper(TL)); +}) + DEF_TRAVERSE_TYPELOC(IncompleteArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); TRY_TO(TraverseArrayTypeLocHelper(TL)); diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 55eca4007d17ea..8892518d58e853 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -583,11 +583,13 @@ class alignas(void *) Stmt { unsigned IsArrow : 1; /// True if this member expression used a nested-name-specifier to - /// refer to the member, e.g., "x->Base::f", or found its member via - /// a using declaration. When true, a MemberExprNameQualifier - /// structure is allocated immediately after the MemberExpr. + /// refer to the member, e.g., "x->Base::f". LLVM_PREFERRED_TYPE(bool) - unsigned HasQualifierOrFoundDecl : 1; + unsigned HasQualifier : 1; + + // True if this member expression found its member via a using declaration. + LLVM_PREFERRED_TYPE(bool) + unsigned HasFoundDecl : 1; /// True if this member expression specified a template keyword /// and/or a template argument list explicitly, e.g., x->f, diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 5d8dde37e76969..99f45d518c7960 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2300,6 +2300,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isConstantArrayType() const; bool isIncompleteArrayType() const; bool isVariableArrayType() const; + bool isArrayParameterType() const; bool isDependentSizedArrayType() const; bool isRecordType() const; bool isClassType() const; @@ -3334,14 +3335,15 @@ class ArrayType : public Type, public llvm::FoldingSetNode { return T->getTypeClass() == ConstantArray || T->getTypeClass() == VariableArray || T->getTypeClass() == IncompleteArray || - T->getTypeClass() == DependentSizedArray; + T->getTypeClass() == DependentSizedArray || + T->getTypeClass() == ArrayParameter; } }; /// Represents the canonical version of C arrays with a specified constant size. /// For example, the canonical type for 'int A[4 + 4*100]' is a /// ConstantArrayType where the element type is 'int' and the size is 404. -class ConstantArrayType final : public ArrayType { +class ConstantArrayType : public ArrayType { friend class ASTContext; // ASTContext creates these. struct ExternalSize { @@ -3382,6 +3384,19 @@ class ConstantArrayType final : public ArrayType { const Expr *SzExpr, ArraySizeModifier SzMod, unsigned Qual); +protected: + ConstantArrayType(TypeClass Tc, const ConstantArrayType *ATy, QualType Can) + : ArrayType(Tc, ATy->getElementType(), Can, ATy->getSizeModifier(), + ATy->getIndexTypeQualifiers().getAsOpaqueValue(), nullptr) { + ConstantArrayTypeBits.HasExternalSize = + ATy->ConstantArrayTypeBits.HasExternalSize; + if (!ConstantArrayTypeBits.HasExternalSize) { + ConstantArrayTypeBits.SizeWidth = ATy->ConstantArrayTypeBits.SizeWidth; + Size = ATy->Size; + } else + SizePtr = ATy->SizePtr; + } + public: /// Return the constant array size as an APInt. llvm::APInt getSize() const { @@ -3453,7 +3468,22 @@ class ConstantArrayType final : public ArrayType { ArraySizeModifier SizeMod, unsigned TypeQuals); static bool classof(const Type *T) { - return T->getTypeClass() == ConstantArray; + return T->getTypeClass() == ConstantArray || + T->getTypeClass() == ArrayParameter; + } +}; + +/// Represents a constant array type that does not decay to a pointer when used +/// as a function parameter. +class ArrayParameterType : public ConstantArrayType { + friend class ASTContext; // ASTContext creates these. + + ArrayParameterType(const ConstantArrayType *ATy, QualType CanTy) + : ConstantArrayType(ArrayParameter, ATy, CanTy) {} + +public: + static bool classof(const Type *T) { + return T->getTypeClass() == ArrayParameter; } }; @@ -7185,7 +7215,8 @@ inline bool QualType::isCanonicalAsParam() const { if (T->isVariablyModifiedType() && T->hasSizedVLAType()) return false; - return !isa(T) && !isa(T); + return !isa(T) && + (!isa(T) || isa(T)); } inline bool QualType::isConstQualified() const { @@ -7450,6 +7481,10 @@ inline bool Type::isVariableArrayType() const { return isa(CanonicalType); } +inline bool Type::isArrayParameterType() const { + return isa(CanonicalType); +} + inline bool Type::isDependentSizedArrayType() const { return isa(CanonicalType); } @@ -7813,7 +7848,7 @@ inline bool Type::isTypedefNameType() const { /// Determines whether this type can decay to a pointer type. inline bool Type::canDecayToPointerType() const { - return isFunctionType() || isArrayType(); + return isFunctionType() || (isArrayType() && !isArrayParameterType()); } inline bool Type::hasPointerRepresentation() const { diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index b09eb3539a4bad..9f2dff7a782cb3 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -1611,6 +1611,11 @@ class ConstantArrayTypeLoc : ConstantArrayType> { }; +/// Wrapper for source info for array parameter types. +class ArrayParameterTypeLoc + : public InheritingConcreteTypeLoc< + ConstantArrayTypeLoc, ArrayParameterTypeLoc, ArrayParameterType> {}; + class IncompleteArrayTypeLoc : public InheritingConcreteTypeLoc; } +let Class = ArrayParameterType in { + def : Creator<[{ return ctx.getAdjustedParameterType( + ctx.getConstantArrayType(elementType,sizeValue, + size,sizeModifier, + indexQualifiers.getCVRQualifiers())); }]>; +} + let Class = IncompleteArrayType in { def : Creator<[{ return ctx.getIncompleteArrayType(elementType, sizeModifier, diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 44035e2fd16f2e..520168f01fd846 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -985,6 +985,7 @@ def FormatSecurity : DiagGroup<"format-security">; def FormatNonStandard : DiagGroup<"format-non-iso">; def FormatY2K : DiagGroup<"format-y2k">; def FormatPedantic : DiagGroup<"format-pedantic">; +def FormatSignedness : DiagGroup<"format-signedness">; def FormatTypeConfusion : DiagGroup<"format-type-confusion">; def FormatOverflowNonKprintf: DiagGroup<"format-overflow-non-kprintf">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 51af81bf1f6fc5..df57f5e6ce11ba 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1748,8 +1748,8 @@ def err_type_defined_in_condition : Error< def err_type_defined_in_enum : Error< "%0 cannot be defined in an enumeration">; def ext_type_defined_in_offsetof : Extension< - "defining a type within '%select{__builtin_offsetof|offsetof}0' is a Clang " - "extension">, InGroup; + "defining a type within '%select{__builtin_offsetof|offsetof}0' is a C23 " + "extension">, InGroup; def note_pure_virtual_function : Note< "unimplemented pure virtual method %0 in %1">; @@ -9821,6 +9821,9 @@ def warn_format_conversion_argument_type_mismatch : Warning< def warn_format_conversion_argument_type_mismatch_pedantic : Extension< warn_format_conversion_argument_type_mismatch.Summary>, InGroup; +def warn_format_conversion_argument_type_mismatch_signedness : Warning< + warn_format_conversion_argument_type_mismatch.Summary>, + InGroup, DefaultIgnore; def warn_format_conversion_argument_type_mismatch_confusion : Warning< warn_format_conversion_argument_type_mismatch.Summary>, InGroup, DefaultIgnore; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 374595edd2ce4a..e1ef7454f01669 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -267,6 +267,9 @@ class TargetInfo : public TransferrableTargetInfo, LLVM_PREFERRED_TYPE(bool) unsigned AllowAMDGPUUnsafeFPAtomics : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned HasUnalignedAccess : 1; + unsigned ARMCDECoprocMask : 8; unsigned MaxOpenCLWorkGroupSize; @@ -859,6 +862,18 @@ class TargetInfo : public TransferrableTargetInfo, return PointerWidth; } + /// Return true iff unaligned accesses are a single instruction (rather than + /// a synthesized sequence). + bool hasUnalignedAccess() const { return HasUnalignedAccess; } + + /// Return true iff unaligned accesses are cheap. This affects placement and + /// size of bitfield loads/stores. (Not the ABI-mandated placement of + /// the bitfields themselves.) + bool hasCheapUnalignedBitFieldAccess() const { + // Simply forward to the unaligned access getter. + return hasUnalignedAccess(); + } + /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro, /// which is the prefix given to user symbols by default. /// diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td index 3625f063758915..fee49cf4326dfc 100644 --- a/clang/include/clang/Basic/TypeNodes.td +++ b/clang/include/clang/Basic/TypeNodes.td @@ -64,6 +64,7 @@ def ConstantArrayType : TypeNode; def IncompleteArrayType : TypeNode; def VariableArrayType : TypeNode; def DependentSizedArrayType : TypeNode, AlwaysDependent; +def ArrayParameterType : TypeNode; def DependentSizedExtVectorType : TypeNode, AlwaysDependent; def DependentAddressSpaceType : TypeNode, AlwaysDependent; def VectorType : TypeNode; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 29066ea14280c2..f5289fb00c895e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3635,6 +3635,9 @@ defm preserve_as_comments : BoolFOption<"preserve-as-comments", "Do not preserve comments in inline assembly">, PosFlag>; def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>; +def reexport_framework : Separate<["-"], "reexport_framework">, Flags<[LinkerInput]>; +def reexport_l : Joined<["-"], "reexport-l">, Flags<[LinkerInput]>; +def reexport_library : JoinedOrSeparate<["-"], "reexport_library">, Flags<[LinkerInput]>; def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group; def freg_struct_return : Flag<["-"], "freg-struct-return">, Group, Visibility<[ClangOption, CC1Option]>, @@ -4507,6 +4510,9 @@ def mwindows : Joined<["-"], "mwindows">, Group; def mdll : Joined<["-"], "mdll">, Group; def municode : Joined<["-"], "municode">, Group; def mthreads : Joined<["-"], "mthreads">, Group; +def marm64x : Joined<["-"], "marm64x">, Group, + Visibility<[ClangOption, CLOption]>, + HelpText<"Link as a hybrid ARM64X image">; def mguard_EQ : Joined<["-"], "mguard=">, Group, HelpText<"Enable or disable Control Flow Guard checks and guard tables emission">, Values<"none,cf,cf-nochecks">; @@ -8307,6 +8313,7 @@ def _SLASH_Fi : CLCompileJoined<"Fi">, def _SLASH_Fo : CLCompileJoined<"Fo">, HelpText<"Set output object file (with /c)">, MetaVarName<"">; +def _SLASH_Fo_COLON : CLCompileJoined<"Fo:">, Alias<_SLASH_Fo>; def _SLASH_guard : CLJoined<"guard:">, HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks. " "Enable EH Continuation Guard with /guard:ehcont">; diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h b/clang/include/clang/ExtractAPI/DeclarationFragments.h index b85a5d21d61217..8a3a22d9a594c6 100644 --- a/clang/include/clang/ExtractAPI/DeclarationFragments.h +++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h @@ -27,8 +27,6 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/Specifiers.h" #include "clang/Lex/MacroInfo.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" #include namespace clang { @@ -315,13 +313,9 @@ class DeclarationFragmentsBuilder { static DeclarationFragments getFragmentsForTemplateParameters(ArrayRef); - static std::string - getNameForTemplateArgument(const ArrayRef, std::string); - - static DeclarationFragments - getFragmentsForTemplateArguments(const ArrayRef, - ASTContext &, - const std::optional>); + static DeclarationFragments getFragmentsForTemplateArguments( + const ArrayRef, ASTContext &, + const std::optional>); static DeclarationFragments getFragmentsForConcept(const ConceptDecl *); @@ -430,12 +424,7 @@ DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) { if (isa(Function) && dyn_cast(Function)->getDescribedFunctionTemplate() && StringRef(ReturnType.begin()->Spelling).starts_with("type-parameter")) { - std::string ProperArgName = - getNameForTemplateArgument(dyn_cast(Function) - ->getDescribedFunctionTemplate() - ->getTemplateParameters() - ->asArray(), - ReturnType.begin()->Spelling); + std::string ProperArgName = Function->getReturnType().getAsString(); ReturnType.begin()->Spelling.swap(ProperArgName); } ReturnType.append(std::move(After)); diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 0720c8283cd75c..48f5fb44157570 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2223,6 +2223,20 @@ struct FormatStyle { /// \version 5 BreakConstructorInitializersStyle BreakConstructorInitializers; + /// If ``true``, clang-format will always break before function definition + /// parameters. + /// \code + /// true: + /// void functionDefinition( + /// int A, int B) {} + /// + /// false: + /// void functionDefinition(int A, int B) {} + /// + /// \endcode + /// \version 19 + bool BreakFunctionDefinitionParameters; + /// Break after each annotation on a field in Java files. /// \code{.java} /// true: false: @@ -4938,6 +4952,8 @@ struct FormatStyle { BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakConstructorInitializers == R.BreakConstructorInitializers && + BreakFunctionDefinitionParameters == + R.BreakFunctionDefinitionParameters && BreakInheritanceList == R.BreakInheritanceList && BreakStringLiterals == R.BreakStringLiterals && BreakTemplateDeclarations == R.BreakTemplateDeclarations && diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index cce91862ae3d03..3464654284f199 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -133,6 +133,24 @@ class CompilerInstance : public ModuleLoader { std::vector> DependencyCollectors; + /// Records the set of modules + class FailedModulesSet { + llvm::StringSet<> Failed; + + public: + bool hasAlreadyFailed(StringRef module) { return Failed.count(module) > 0; } + + void addFailed(StringRef module) { Failed.insert(module); } + }; + + /// The set of modules that failed to build. + /// + /// This pointer will be shared among all of the compiler instances created + /// to (re)build modules, so that once a module fails to build anywhere, + /// other instances will see that the module has failed and won't try to + /// build it again. + std::shared_ptr FailedModules; + /// The set of top-level modules that has already been built on the /// fly as part of this overall compilation action. std::map> BuiltModules; @@ -619,6 +637,24 @@ class CompilerInstance : public ModuleLoader { } /// @} + /// @name Failed modules set + /// @{ + + bool hasFailedModulesSet() const { return (bool)FailedModules; } + + void createFailedModulesSet() { + FailedModules = std::make_shared(); + } + + std::shared_ptr getFailedModulesSetPtr() const { + return FailedModules; + } + + void setFailedModulesSet(std::shared_ptr FMS) { + FailedModules = FMS; + } + + /// } /// @name Output Files /// @{ diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h index a620ddfc40447d..0518a8823a03ea 100644 --- a/clang/include/clang/Frontend/FrontendActions.h +++ b/clang/include/clang/Frontend/FrontendActions.h @@ -34,12 +34,18 @@ class InitOnlyAction : public FrontendAction { /// Preprocessor-based frontend action that also loads PCH files. class ReadPCHAndPreprocessAction : public FrontendAction { + llvm::unique_function AdjustCI; + void ExecuteAction() override; std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override; public: + ReadPCHAndPreprocessAction( + llvm::unique_function AdjustCI) + : AdjustCI(std::move(AdjustCI)) {} + bool usesPreprocessorOnly() const override { return false; } }; @@ -321,11 +327,15 @@ class PrintPreprocessedAction : public PreprocessorFrontendAction { class GetDependenciesByModuleNameAction : public PreprocessOnlyAction { StringRef ModuleName; + llvm::unique_function AdjustCI; + void ExecuteAction() override; public: - GetDependenciesByModuleNameAction(StringRef ModuleName) - : ModuleName(ModuleName) {} + GetDependenciesByModuleNameAction( + StringRef ModuleName, + llvm::unique_function AdjustCI) + : ModuleName(ModuleName), AdjustCI(std::move(AdjustCI)) {} }; } // end namespace clang diff --git a/clang/include/clang/InstallAPI/DylibVerifier.h b/clang/include/clang/InstallAPI/DylibVerifier.h index 49de24763f1f93..22cdc234486cf3 100644 --- a/clang/include/clang/InstallAPI/DylibVerifier.h +++ b/clang/include/clang/InstallAPI/DylibVerifier.h @@ -31,6 +31,7 @@ enum class VerificationMode { class DylibVerifier : llvm::MachO::RecordVisitor { private: struct SymbolContext; + struct DWARFContext; public: enum class Result { NoVerify, Ignore, Valid, Invalid }; @@ -54,7 +55,7 @@ class DylibVerifier : llvm::MachO::RecordVisitor { DiagnosticsEngine *Diag = nullptr; // Handle diagnostics reporting for target level violations. - void emitDiag(llvm::function_ref Report); + void emitDiag(llvm::function_ref Report, RecordLoc *Loc = nullptr); VerifierContext() = default; VerifierContext(DiagnosticsEngine *Diag) : Diag(Diag) {} @@ -63,9 +64,10 @@ class DylibVerifier : llvm::MachO::RecordVisitor { DylibVerifier() = default; DylibVerifier(llvm::MachO::Records &&Dylib, DiagnosticsEngine *Diag, - VerificationMode Mode, bool Demangle) + VerificationMode Mode, bool Demangle, StringRef DSYMPath) : Dylib(std::move(Dylib)), Mode(Mode), Demangle(Demangle), - Exports(std::make_unique()), Ctx(VerifierContext{Diag}) {} + DSYMPath(DSYMPath), Exports(std::make_unique()), + Ctx(VerifierContext{Diag}) {} Result verify(GlobalRecord *R, const FrontendAttrs *FA); Result verify(ObjCInterfaceRecord *R, const FrontendAttrs *FA); @@ -143,6 +145,12 @@ class DylibVerifier : llvm::MachO::RecordVisitor { std::string getAnnotatedName(const Record *R, SymbolContext &SymCtx, bool ValidSourceLoc = true); + /// Extract source location for symbol implementations. + /// As this is a relatively expensive operation, it is only used + /// when there is a violation to report and there is not a known declaration + /// in the interface. + void accumulateSrcLocForDylibSymbols(); + // Symbols in dylib. llvm::MachO::Records Dylib; @@ -152,11 +160,17 @@ class DylibVerifier : llvm::MachO::RecordVisitor { // Attempt to demangle when reporting violations. bool Demangle = false; + // File path to DSYM file. + StringRef DSYMPath; + // Valid symbols in final text file. std::unique_ptr Exports = std::make_unique(); // Track current state of verification while traversing AST. VerifierContext Ctx; + + // Track DWARF provided source location for dylibs. + DWARFContext *DWARFCtx = nullptr; }; } // namespace installapi diff --git a/clang/include/clang/InstallAPI/MachO.h b/clang/include/clang/InstallAPI/MachO.h index 4961c596fd68ae..827220dbf39fb8 100644 --- a/clang/include/clang/InstallAPI/MachO.h +++ b/clang/include/clang/InstallAPI/MachO.h @@ -34,6 +34,7 @@ using ObjCCategoryRecord = llvm::MachO::ObjCCategoryRecord; using ObjCIVarRecord = llvm::MachO::ObjCIVarRecord; using ObjCIFSymbolKind = llvm::MachO::ObjCIFSymbolKind; using Records = llvm::MachO::Records; +using RecordLoc = llvm::MachO::RecordLoc; using RecordsSlice = llvm::MachO::RecordsSlice; using BinaryAttrs = llvm::MachO::RecordsSlice::BinaryAttrs; using SymbolSet = llvm::MachO::SymbolSet; diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 0836b7d439bb04..24e146a589a758 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -736,6 +736,19 @@ class Preprocessor { State ConditionalStackState = Off; } PreambleConditionalStack; + /// Function for getting the dependency preprocessor directives of a file. + /// + /// These are directives derived from a special form of lexing where the + /// source input is scanned for the preprocessor directives that might have an + /// effect on the dependencies for a compilation unit. + /// + /// Enables a client to cache the directives for a file and provide them + /// across multiple compiler invocations. + /// FIXME: Allow returning an error. + using DependencyDirectivesFn = llvm::unique_function>(FileEntryRef)>; + DependencyDirectivesFn DependencyDirectivesForFile; + /// The current top of the stack that we're lexing from if /// not expanding a macro and we are lexing directly from source code. /// @@ -1270,6 +1283,11 @@ class Preprocessor { /// false if it is producing tokens to be consumed by Parse and Sema. bool isPreprocessedOutput() const { return PreprocessedOutput; } + /// Set the function used to get dependency directives for a file. + void setDependencyDirectivesFn(DependencyDirectivesFn Fn) { + DependencyDirectivesForFile = std::move(Fn); + } + /// Return true if we are lexing directly from the specified lexer. bool isCurrentLexer(const PreprocessorLexer *L) const { return CurPPLexer == L; diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h index f841e4a028df50..50b5fba0ff773e 100644 --- a/clang/include/clang/Lex/PreprocessorOptions.h +++ b/clang/include/clang/Lex/PreprocessorOptions.h @@ -186,41 +186,6 @@ class PreprocessorOptions { /// with support for lifetime-qualified pointers. ObjCXXARCStandardLibraryKind ObjCXXARCStandardLibrary = ARCXX_nolib; - /// Records the set of modules - class FailedModulesSet { - llvm::StringSet<> Failed; - - public: - bool hasAlreadyFailed(StringRef module) { - return Failed.count(module) > 0; - } - - void addFailed(StringRef module) { - Failed.insert(module); - } - }; - - /// The set of modules that failed to build. - /// - /// This pointer will be shared among all of the compiler instances created - /// to (re)build modules, so that once a module fails to build anywhere, - /// other instances will see that the module has failed and won't try to - /// build it again. - std::shared_ptr FailedModules; - - /// Function for getting the dependency preprocessor directives of a file. - /// - /// These are directives derived from a special form of lexing where the - /// source input is scanned for the preprocessor directives that might have an - /// effect on the dependencies for a compilation unit. - /// - /// Enables a client to cache the directives for a file and provide them - /// across multiple compiler invocations. - /// FIXME: Allow returning an error. - std::function>( - FileEntryRef)> - DependencyDirectivesForFile; - /// Set up preprocessor for RunAnalysis action. bool SetUpStaticAnalyzer = false; diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index e4717dd5baf1e8..76311b00d2fc58 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -198,6 +198,9 @@ class Sema; /// HLSL vector truncation. ICK_HLSL_Vector_Truncation, + /// HLSL non-decaying array rvalue cast. + ICK_HLSL_Array_RValue, + /// The number of conversion kinds ICK_Num_Conversion_Kinds, }; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 3fcb963e752f3a..8c98d8c7fef7a7 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -33,7 +33,6 @@ #include "clang/AST/NSAPI.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/StmtCXX.h" -#include "clang/AST/StmtOpenACC.h" #include "clang/AST/StmtOpenMP.h" #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeOrdering.h" @@ -42,7 +41,6 @@ #include "clang/Basic/DarwinSDKInfo.h" #include "clang/Basic/ExpressionTraits.h" #include "clang/Basic/Module.h" -#include "clang/Basic/OpenACCKinds.h" #include "clang/Basic/OpenCLOptions.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/PragmaKinds.h" @@ -183,6 +181,7 @@ class Preprocessor; class PseudoDestructorTypeStorage; class PseudoObjectExpr; class QualType; +class SemaOpenACC; class StandardConversionSequence; class Stmt; class StringLiteral; @@ -466,9 +465,8 @@ class Sema final { // 37. Name Lookup for RISC-V Vector Intrinsic (SemaRISCVVectorLookup.cpp) // 38. CUDA (SemaCUDA.cpp) // 39. HLSL Constructs (SemaHLSL.cpp) - // 40. OpenACC Constructs (SemaOpenACC.cpp) - // 41. OpenMP Directives and Clauses (SemaOpenMP.cpp) - // 42. SYCL Constructs (SemaSYCL.cpp) + // 40. OpenMP Directives and Clauses (SemaOpenMP.cpp) + // 41. SYCL Constructs (SemaSYCL.cpp) /// \name Semantic Analysis /// Implementations are in Sema.cpp @@ -1162,6 +1160,11 @@ class Sema final { /// CurContext - This is the current declaration context of parsing. DeclContext *CurContext; + SemaOpenACC &OpenACC() { + assert(OpenACCPtr); + return *OpenACCPtr; + } + protected: friend class Parser; friend class InitializationSequence; @@ -1192,6 +1195,8 @@ class Sema final { mutable IdentifierInfo *Ident_super; + std::unique_ptr OpenACCPtr; + ///@} // @@ -13354,56 +13359,6 @@ class Sema final { // // - /// \name OpenACC Constructs - /// Implementations are in SemaOpenACC.cpp - ///@{ - -public: - /// Called after parsing an OpenACC Clause so that it can be checked. - bool ActOnOpenACCClause(OpenACCClauseKind ClauseKind, - SourceLocation StartLoc); - - /// Called after the construct has been parsed, but clauses haven't been - /// parsed. This allows us to diagnose not-implemented, as well as set up any - /// state required for parsing the clauses. - void ActOnOpenACCConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc); - - /// Called after the directive, including its clauses, have been parsed and - /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES - /// happen before any associated declarations or statements have been parsed. - /// This function is only called when we are parsing a 'statement' context. - bool ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc); - - /// Called after the directive, including its clauses, have been parsed and - /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES - /// happen before any associated declarations or statements have been parsed. - /// This function is only called when we are parsing a 'Decl' context. - bool ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc); - /// Called when we encounter an associated statement for our construct, this - /// should check legality of the statement as it appertains to this Construct. - StmtResult ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K, - StmtResult AssocStmt); - - /// Called after the directive has been completely parsed, including the - /// declaration group or associated statement. - StmtResult ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc, - SourceLocation EndLoc, - StmtResult AssocStmt); - /// Called after the directive has been completely parsed, including the - /// declaration group or associated statement. - DeclGroupRef ActOnEndOpenACCDeclDirective(); - - ///@} - - // - // - // ------------------------------------------------------------------------- - // - // - /// \name OpenMP Directives and Clauses /// Implementations are in SemaOpenMP.cpp ///@{ diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h new file mode 100644 index 00000000000000..7f50d7889ad79b --- /dev/null +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -0,0 +1,74 @@ +//===----- SemaOpenACC.h - Semantic Analysis for OpenACC constructs -------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares semantic analysis for OpenACC constructs and +/// clauses. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_SEMAOPENACC_H +#define LLVM_CLANG_SEMA_SEMAOPENACC_H + +#include "clang/AST/DeclGroup.h" +#include "clang/Basic/OpenACCKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Sema/Ownership.h" + +namespace clang { + +class ASTContext; +class DiagnosticEngine; +class LangOptions; +class Sema; + +class SemaOpenACC { +public: + SemaOpenACC(Sema &S); + + ASTContext &getASTContext() const; + DiagnosticsEngine &getDiagnostics() const; + const LangOptions &getLangOpts() const; + + Sema &SemaRef; + + /// Called after parsing an OpenACC Clause so that it can be checked. + bool ActOnClause(OpenACCClauseKind ClauseKind, SourceLocation StartLoc); + + /// Called after the construct has been parsed, but clauses haven't been + /// parsed. This allows us to diagnose not-implemented, as well as set up any + /// state required for parsing the clauses. + void ActOnConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc); + + /// Called after the directive, including its clauses, have been parsed and + /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES + /// happen before any associated declarations or statements have been parsed. + /// This function is only called when we are parsing a 'statement' context. + bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc); + + /// Called after the directive, including its clauses, have been parsed and + /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES + /// happen before any associated declarations or statements have been parsed. + /// This function is only called when we are parsing a 'Decl' context. + bool ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc); + /// Called when we encounter an associated statement for our construct, this + /// should check legality of the statement as it appertains to this Construct. + StmtResult ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt); + + /// Called after the directive has been completely parsed, including the + /// declaration group or associated statement. + StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, + SourceLocation StartLoc, + SourceLocation EndLoc, StmtResult AssocStmt); + /// Called after the directive has been completely parsed, including the + /// declaration group or associated statement. + DeclGroupRef ActOnEndDeclDirective(); +}; + +} // namespace clang + +#endif // LLVM_CLANG_SEMA_SEMAOPENACC_H diff --git a/clang/include/clang/Serialization/TypeBitCodes.def b/clang/include/clang/Serialization/TypeBitCodes.def index 3c82dfed9497d5..82b053d4caca63 100644 --- a/clang/include/clang/Serialization/TypeBitCodes.def +++ b/clang/include/clang/Serialization/TypeBitCodes.def @@ -66,5 +66,6 @@ TYPE_BIT_CODE(Using, USING, 54) TYPE_BIT_CODE(BTFTagAttributed, BTFTAG_ATTRIBUTED, 55) TYPE_BIT_CODE(PackIndexing, PACK_INDEXING, 56) TYPE_BIT_CODE(CountAttributed, COUNT_ATTRIBUTED, 57) +TYPE_BIT_CODE(ArrayParameter, ARRAY_PARAMETER, 58) #undef TYPE_BIT_CODE diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index c90fafb6f653d0..f7f55dc4e7a9f4 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -879,7 +879,8 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, TemplateSpecializationTypes(this_()), DependentTemplateSpecializationTypes(this_()), AutoTypes(this_()), DependentBitIntTypes(this_()), SubstTemplateTemplateParmPacks(this_()), - CanonTemplateTemplateParms(this_()), SourceMgr(SM), LangOpts(LOpts), + ArrayParameterTypes(this_()), CanonTemplateTemplateParms(this_()), + SourceMgr(SM), LangOpts(LOpts), NoSanitizeL(new NoSanitizeList(LangOpts.NoSanitizeFiles, SM)), XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles, LangOpts.XRayNeverInstrumentFiles, @@ -1906,7 +1907,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { case Type::IncompleteArray: case Type::VariableArray: - case Type::ConstantArray: { + case Type::ConstantArray: + case Type::ArrayParameter: { // Model non-constant sized arrays as size zero, but track the alignment. uint64_t Size = 0; if (const auto *CAT = dyn_cast(T)) @@ -3396,6 +3398,37 @@ QualType ASTContext::getDecayedType(QualType T) const { return getDecayedType(T, Decayed); } +QualType ASTContext::getArrayParameterType(QualType Ty) const { + if (Ty->isArrayParameterType()) + return Ty; + assert(Ty->isConstantArrayType() && "Ty must be an array type."); + const auto *ATy = cast(Ty); + llvm::FoldingSetNodeID ID; + ATy->Profile(ID, *this, ATy->getElementType(), ATy->getZExtSize(), + ATy->getSizeExpr(), ATy->getSizeModifier(), + ATy->getIndexTypeQualifiers().getAsOpaqueValue()); + void *InsertPos = nullptr; + ArrayParameterType *AT = + ArrayParameterTypes.FindNodeOrInsertPos(ID, InsertPos); + if (AT) + return QualType(AT, 0); + + QualType Canonical; + if (!Ty.isCanonical()) { + Canonical = getArrayParameterType(getCanonicalType(Ty)); + + // Get the new insert position for the node we care about. + AT = ArrayParameterTypes.FindNodeOrInsertPos(ID, InsertPos); + assert(!AT && "Shouldn't be in the map!"); + } + + AT = new (*this, alignof(ArrayParameterType)) + ArrayParameterType(ATy, Canonical); + Types.push_back(AT); + ArrayParameterTypes.InsertNode(AT, InsertPos); + return QualType(AT, 0); +} + /// getBlockPointerType - Return the uniqued reference to the type for /// a pointer to the specified block. QualType ASTContext::getBlockPointerType(QualType T) const { @@ -3642,6 +3675,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const { case Type::PackIndexing: case Type::BitInt: case Type::DependentBitInt: + case Type::ArrayParameter: llvm_unreachable("type should never be variably-modified"); // These types can be variably-modified but should never need to @@ -6051,7 +6085,9 @@ CanQualType ASTContext::getCanonicalParamType(QualType T) const { T = getVariableArrayDecayedType(T); const Type *Ty = T.getTypePtr(); QualType Result; - if (isa(Ty)) { + if (getLangOpts().HLSL && isa(Ty)) { + Result = getArrayParameterType(QualType(Ty, 0)); + } else if (isa(Ty)) { Result = getArrayDecayedType(QualType(Ty,0)); } else if (isa(Ty)) { Result = getPointerType(QualType(Ty, 0)); @@ -6973,6 +7009,8 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const { } QualType ASTContext::getAdjustedParameterType(QualType T) const { + if (getLangOpts().HLSL && T->isConstantArrayType()) + return getArrayParameterType(T); if (T->isArrayType() || T->isFunctionType()) return getDecayedType(T); return T; @@ -8583,6 +8621,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, case Type::DeducedTemplateSpecialization: return; + case Type::ArrayParameter: case Type::Pipe: #define ABSTRACT_TYPE(KIND, BASE) #define TYPE(KIND, BASE) @@ -10926,6 +10965,10 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, bool OfBlockPointer, assert(LHS != RHS && "Equivalent pipe types should have already been handled!"); return {}; + case Type::ArrayParameter: + assert(LHS != RHS && + "Equivalent ArrayParameter types should have already been handled!"); + return {}; case Type::BitInt: { // Merge two bit-precise int types, while trying to preserve typedef info. bool LHSUnsigned = LHS->castAs()->isUnsigned(); @@ -12817,6 +12860,18 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X, getCommonArrayElementType(Ctx, AX, QX, AY, QY), AX->getSize(), SizeExpr, getCommonSizeModifier(AX, AY), getCommonIndexTypeCVRQualifiers(AX, AY)); } + case Type::ArrayParameter: { + const auto *AX = cast(X), + *AY = cast(Y); + assert(AX->getSize() == AY->getSize()); + const Expr *SizeExpr = Ctx.hasSameExpr(AX->getSizeExpr(), AY->getSizeExpr()) + ? AX->getSizeExpr() + : nullptr; + auto ArrayTy = Ctx.getConstantArrayType( + getCommonArrayElementType(Ctx, AX, QX, AY, QY), AX->getSize(), SizeExpr, + getCommonSizeModifier(AX, AY), getCommonIndexTypeCVRQualifiers(AX, AY)); + return Ctx.getArrayParameterType(ArrayTy); + } case Type::Atomic: { const auto *AX = cast(X), *AY = cast(Y); return Ctx.getAtomicType( @@ -13078,6 +13133,7 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X, CANONICAL_TYPE(Builtin) CANONICAL_TYPE(Complex) CANONICAL_TYPE(ConstantArray) + CANONICAL_TYPE(ArrayParameter) CANONICAL_TYPE(ConstantMatrix) CANONICAL_TYPE(Enum) CANONICAL_TYPE(ExtVector) diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 786695f00fadcc..94a47a8f619018 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1218,6 +1218,15 @@ ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) { T->getIndexTypeCVRQualifiers()); } +ExpectedType +ASTNodeImporter::VisitArrayParameterType(const ArrayParameterType *T) { + ExpectedType ToArrayTypeOrErr = VisitConstantArrayType(T); + if (!ToArrayTypeOrErr) + return ToArrayTypeOrErr.takeError(); + + return Importer.getToContext().getArrayParameterType(*ToArrayTypeOrErr); +} + ExpectedType ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) { ExpectedType ToElementTypeOrErr = import(T->getElementType()); diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp index 226e0aa38ece70..d56bf21b459e03 100644 --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -840,6 +840,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, case Type::Adjusted: case Type::Decayed: + case Type::ArrayParameter: if (!IsStructurallyEquivalent(Context, cast(T1)->getOriginalType(), cast(T2)->getOriginalType())) diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index 9d3856b8f7e08a..86b77b49a0fbc4 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -654,6 +654,9 @@ ExprDependence clang::computeDependence(MemberExpr *E) { D |= toExprDependence(NNS->getDependence() & ~NestedNameSpecifierDependence::Dependent); + for (const auto &A : E->template_arguments()) + D |= toExprDependence(A.getArgument().getDependence()); + auto *MemberDecl = E->getMemberDecl(); if (FieldDecl *FD = dyn_cast(MemberDecl)) { DeclContext *DC = MemberDecl->getDeclContext(); @@ -670,7 +673,6 @@ ExprDependence clang::computeDependence(MemberExpr *E) { D |= ExprDependence::Type; } } - // FIXME: move remaining dependence computation from MemberExpr::Create() return D; } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 04bbc49ab2f319..2cbb86b31b5e2e 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1102,9 +1102,13 @@ bool Decl::isInAnotherModuleUnit() const { return M != getASTContext().getCurrentNamedModule(); } +bool Decl::isFromExplicitGlobalModule() const { + return getOwningModule() && getOwningModule()->isExplicitGlobalModule(); +} + bool Decl::shouldSkipCheckingODR() const { - return getASTContext().getLangOpts().SkipODRCheckInGMF && getOwningModule() && - getOwningModule()->isExplicitGlobalModule(); + return getASTContext().getLangOpts().SkipODRCheckInGMF && + isFromExplicitGlobalModule(); } static Decl::Kind getKind(const Decl *D) { return D->getKind(); } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 6221ebd5c9b4e9..07c9f287dd0767 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1712,8 +1712,11 @@ UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr( } MemberExpr::MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc, - ValueDecl *MemberDecl, - const DeclarationNameInfo &NameInfo, QualType T, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, ValueDecl *MemberDecl, + DeclAccessPair FoundDecl, + const DeclarationNameInfo &NameInfo, + const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR) : Expr(MemberExprClass, T, VK, OK), Base(Base), MemberDecl(MemberDecl), @@ -1721,11 +1724,30 @@ MemberExpr::MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc, assert(!NameInfo.getName() || MemberDecl->getDeclName() == NameInfo.getName()); MemberExprBits.IsArrow = IsArrow; - MemberExprBits.HasQualifierOrFoundDecl = false; - MemberExprBits.HasTemplateKWAndArgsInfo = false; + MemberExprBits.HasQualifier = QualifierLoc.hasQualifier(); + MemberExprBits.HasFoundDecl = + FoundDecl.getDecl() != MemberDecl || + FoundDecl.getAccess() != MemberDecl->getAccess(); + MemberExprBits.HasTemplateKWAndArgsInfo = + TemplateArgs || TemplateKWLoc.isValid(); MemberExprBits.HadMultipleCandidates = false; MemberExprBits.NonOdrUseReason = NOUR; MemberExprBits.OperatorLoc = OperatorLoc; + + if (hasQualifier()) + new (getTrailingObjects()) + NestedNameSpecifierLoc(QualifierLoc); + if (hasFoundDecl()) + *getTrailingObjects() = FoundDecl; + if (TemplateArgs) { + auto Deps = TemplateArgumentDependence::None; + getTrailingObjects()->initializeFrom( + TemplateKWLoc, *TemplateArgs, getTrailingObjects(), + Deps); + } else if (TemplateKWLoc.isValid()) { + getTrailingObjects()->initializeFrom( + TemplateKWLoc); + } setDependence(computeDependence(this)); } @@ -1735,48 +1757,20 @@ MemberExpr *MemberExpr::Create( ValueDecl *MemberDecl, DeclAccessPair FoundDecl, DeclarationNameInfo NameInfo, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR) { - bool HasQualOrFound = QualifierLoc || FoundDecl.getDecl() != MemberDecl || - FoundDecl.getAccess() != MemberDecl->getAccess(); + bool HasQualifier = QualifierLoc.hasQualifier(); + bool HasFoundDecl = FoundDecl.getDecl() != MemberDecl || + FoundDecl.getAccess() != MemberDecl->getAccess(); bool HasTemplateKWAndArgsInfo = TemplateArgs || TemplateKWLoc.isValid(); std::size_t Size = - totalSizeToAlloc( - HasQualOrFound ? 1 : 0, HasTemplateKWAndArgsInfo ? 1 : 0, + totalSizeToAlloc( + HasQualifier, HasFoundDecl, HasTemplateKWAndArgsInfo, TemplateArgs ? TemplateArgs->size() : 0); void *Mem = C.Allocate(Size, alignof(MemberExpr)); - MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl, - NameInfo, T, VK, OK, NOUR); - - if (HasQualOrFound) { - E->MemberExprBits.HasQualifierOrFoundDecl = true; - - MemberExprNameQualifier *NQ = - E->getTrailingObjects(); - NQ->QualifierLoc = QualifierLoc; - NQ->FoundDecl = FoundDecl; - } - - E->MemberExprBits.HasTemplateKWAndArgsInfo = - TemplateArgs || TemplateKWLoc.isValid(); - - // FIXME: remove remaining dependence computation to computeDependence(). - auto Deps = E->getDependence(); - if (TemplateArgs) { - auto TemplateArgDeps = TemplateArgumentDependence::None; - E->getTrailingObjects()->initializeFrom( - TemplateKWLoc, *TemplateArgs, - E->getTrailingObjects(), TemplateArgDeps); - for (const TemplateArgumentLoc &ArgLoc : TemplateArgs->arguments()) { - Deps |= toExprDependence(ArgLoc.getArgument().getDependence()); - } - } else if (TemplateKWLoc.isValid()) { - E->getTrailingObjects()->initializeFrom( - TemplateKWLoc); - } - E->setDependence(Deps); - - return E; + return new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, QualifierLoc, + TemplateKWLoc, MemberDecl, FoundDecl, NameInfo, + TemplateArgs, T, VK, OK, NOUR); } MemberExpr *MemberExpr::CreateEmpty(const ASTContext &Context, @@ -1785,12 +1779,11 @@ MemberExpr *MemberExpr::CreateEmpty(const ASTContext &Context, unsigned NumTemplateArgs) { assert((!NumTemplateArgs || HasTemplateKWAndArgsInfo) && "template args but no template arg info?"); - bool HasQualOrFound = HasQualifier || HasFoundDecl; std::size_t Size = - totalSizeToAlloc(HasQualOrFound ? 1 : 0, - HasTemplateKWAndArgsInfo ? 1 : 0, - NumTemplateArgs); + totalSizeToAlloc( + HasQualifier, HasFoundDecl, HasTemplateKWAndArgsInfo, + NumTemplateArgs); void *Mem = Context.Allocate(Size, alignof(MemberExpr)); return new (Mem) MemberExpr(EmptyShell()); } @@ -1948,6 +1941,7 @@ bool CastExpr::CastConsistency() const { case CK_UserDefinedConversion: // operator bool() case CK_BuiltinFnToFnPtr: case CK_FixedPointToBoolean: + case CK_HLSLArrayRValue: CheckNoBasePath: assert(path_empty() && "Cast kind should not have a base path!"); break; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 5a36621dc5cce2..88c8eaf6ef9b6e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6456,7 +6456,7 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This, // Non-virtual base classes are initialized in the order in the class // definition. We have already checked for virtual base classes. assert(!BaseIt->isVirtual() && "virtual base for literal type"); - assert(Info.Ctx.hasSameType(BaseIt->getType(), BaseType) && + assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->getType(), BaseType) && "base class initializers not in expected order"); ++BaseIt; #endif @@ -11699,6 +11699,7 @@ GCCTypeClass EvaluateBuiltinClassifyType(QualType T, case Type::IncompleteArray: case Type::FunctionNoProto: case Type::FunctionProto: + case Type::ArrayParameter: return GCCTypeClass::Pointer; case Type::MemberPointer: @@ -12361,12 +12362,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, if (!EvaluateInteger(E->getArg(0), Val, Info)) return false; + std::optional Fallback; + if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) { + APSInt FallbackTemp; + if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info)) + return false; + Fallback = FallbackTemp; + } + if (!Val) { - if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) { - if (!EvaluateInteger(E->getArg(1), Val, Info)) - return false; - return Success(Val, E); - } + if (Fallback) + return Success(*Fallback, E); // When the argument is 0, the result of GCC builtins is undefined, // whereas for Microsoft intrinsics, the result is the bit-width of the @@ -12425,12 +12431,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, if (!EvaluateInteger(E->getArg(0), Val, Info)) return false; + std::optional Fallback; + if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) { + APSInt FallbackTemp; + if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info)) + return false; + Fallback = FallbackTemp; + } + if (!Val) { - if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) { - if (!EvaluateInteger(E->getArg(1), Val, Info)) - return false; - return Success(Val, E); - } + if (Fallback) + return Success(*Fallback, E); return Error(E); } @@ -14075,6 +14086,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { case CK_AtomicToNonAtomic: case CK_NoOp: case CK_LValueToRValueBitCast: + case CK_HLSLArrayRValue: return ExprEvaluatorBaseTy::VisitCastExpr(E); case CK_MemberPointerToBoolean: @@ -14903,6 +14915,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) { case CK_AtomicToNonAtomic: case CK_NoOp: case CK_LValueToRValueBitCast: + case CK_HLSLArrayRValue: return ExprEvaluatorBaseTy::VisitCastExpr(E); case CK_Dependent: diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp index 0c80ad109ccbb2..da8164bad518ec 100644 --- a/clang/lib/AST/FormatString.cpp +++ b/clang/lib/AST/FormatString.cpp @@ -413,7 +413,7 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { return Match; if (const auto *BT = argTy->getAs()) { // Check if the only difference between them is signed vs unsigned - // if true, we consider they are compatible. + // if true, return match signedness. switch (BT->getKind()) { default: break; @@ -423,44 +423,53 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { [[fallthrough]]; case BuiltinType::Char_S: case BuiltinType::SChar: + if (T == C.UnsignedShortTy || T == C.ShortTy) + return NoMatchTypeConfusion; + if (T == C.UnsignedCharTy) + return NoMatchSignedness; + if (T == C.SignedCharTy) + return Match; + break; case BuiltinType::Char_U: case BuiltinType::UChar: if (T == C.UnsignedShortTy || T == C.ShortTy) return NoMatchTypeConfusion; - if (T == C.UnsignedCharTy || T == C.SignedCharTy) + if (T == C.UnsignedCharTy) return Match; + if (T == C.SignedCharTy) + return NoMatchSignedness; break; case BuiltinType::Short: if (T == C.UnsignedShortTy) - return Match; + return NoMatchSignedness; break; case BuiltinType::UShort: if (T == C.ShortTy) - return Match; + return NoMatchSignedness; break; case BuiltinType::Int: if (T == C.UnsignedIntTy) - return Match; + return NoMatchSignedness; break; case BuiltinType::UInt: if (T == C.IntTy) - return Match; + return NoMatchSignedness; break; case BuiltinType::Long: if (T == C.UnsignedLongTy) - return Match; + return NoMatchSignedness; break; case BuiltinType::ULong: if (T == C.LongTy) - return Match; + return NoMatchSignedness; break; case BuiltinType::LongLong: if (T == C.UnsignedLongLongTy) - return Match; + return NoMatchSignedness; break; case BuiltinType::ULongLong: if (T == C.LongLongTy) - return Match; + return NoMatchSignedness; break; } // "Partially matched" because of promotions? diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.h b/clang/lib/AST/Interp/ByteCodeStmtGen.h index ab7a591fb798ee..d7e6e5042c2740 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.h +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.h @@ -82,6 +82,7 @@ class ByteCodeStmtGen final : public ByteCodeExprGen { OptLabelTy DefaultLabel; }; +extern template class ByteCodeStmtGen; extern template class ByteCodeExprGen; } // namespace interp diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 425f84e8af1fe7..d632c697fa20db 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2398,6 +2398,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, case Type::Complex: case Type::Adjusted: case Type::Decayed: + case Type::ArrayParameter: case Type::Pointer: case Type::BlockPointer: case Type::LValueReference: @@ -4446,6 +4447,10 @@ void CXXNameMangler::mangleType(const DependentBitIntType *T) { Out << "_"; } +void CXXNameMangler::mangleType(const ArrayParameterType *T) { + mangleType(cast(T)); +} + void CXXNameMangler::mangleIntegerLiteral(QualType T, const llvm::APSInt &Value) { // ::= L E # integer literal diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index addc3140546a46..a0bb04e69c9be8 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -3079,6 +3079,11 @@ void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) { mangleType(ElementTy, SourceRange(), QMM_Escape); } +void MicrosoftCXXNameMangler::mangleType(const ArrayParameterType *T, + Qualifiers, SourceRange) { + mangleArrayType(cast(T)); +} + // ::= // ::= // diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 2dbc259138a897..e159a1b00be552 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -944,6 +944,10 @@ class ODRTypeVisitor : public TypeVisitor { VisitArrayType(T); } + void VisitArrayParameterType(const ArrayParameterType *T) { + VisitConstantArrayType(T); + } + void VisitDependentSizedArrayType(const DependentSizedArrayType *T) { AddStmt(T->getSizeExpr()); VisitArrayType(T); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 47fdbfe21e5884..cb22c91a12aa89 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1197,6 +1197,14 @@ struct SimpleTransformVisitor : public TypeVisitor { return Ctx.getDecayedType(originalType); } + QualType VisitArrayParameterType(const ArrayParameterType *T) { + QualType ArrTy = VisitConstantArrayType(T); + if (ArrTy.isNull()) + return {}; + + return Ctx.getArrayParameterType(ArrTy); + } + SUGARED_TYPE_CLASS(TypeOfExpr) SUGARED_TYPE_CLASS(TypeOf) SUGARED_TYPE_CLASS(Decltype) @@ -4454,6 +4462,7 @@ static CachedProperties computeCachedProperties(const Type *T) { case Type::ConstantArray: case Type::IncompleteArray: case Type::VariableArray: + case Type::ArrayParameter: return Cache::get(cast(T)->getElementType()); case Type::Vector: case Type::ExtVector: @@ -4542,6 +4551,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) { case Type::ConstantArray: case Type::IncompleteArray: case Type::VariableArray: + case Type::ArrayParameter: return computeTypeLinkageInfo(cast(T)->getElementType()); case Type::Vector: case Type::ExtVector: @@ -4745,6 +4755,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { case Type::Pipe: case Type::BitInt: case Type::DependentBitInt: + case Type::ArrayParameter: return false; } llvm_unreachable("bad type kind!"); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 0aa1d9327d7707..9d551ff83151fd 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -268,6 +268,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T, case Type::Adjusted: case Type::Decayed: + case Type::ArrayParameter: case Type::Pointer: case Type::BlockPointer: case Type::LValueReference: @@ -595,6 +596,16 @@ void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) { printAdjustedBefore(T, OS); } +void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T, + raw_ostream &OS) { + printConstantArrayAfter(T, OS); +} + +void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T, + raw_ostream &OS) { + printConstantArrayBefore(T, OS); +} + void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) { printAdjustedAfter(T, OS); } diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 5d9055174c089a..f96956f31d50dc 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -157,6 +157,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) { HasAArch64SVETypes = false; HasRISCVVTypes = false; AllowAMDGPUUnsafeFPAtomics = false; + HasUnalignedAccess = false; ARMCDECoprocMask = 0; // Default to no types using fpret. diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 1c3199bd76eed6..1569b5e04b770a 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -188,6 +188,8 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, assert(UseBitFieldTypeAlignment && "bitfields affect type alignment"); UseZeroLengthBitfieldAlignment = true; + HasUnalignedAccess = true; + // AArch64 targets default to using the ARM C++ ABI. TheCXXABI.set(TargetCXXABI::GenericAArch64); @@ -496,7 +498,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasPAuthLR) Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1"); - if (HasUnaligned) + if (HasUnalignedAccess) Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); if ((FPU & NeonMode) && HasFullFP16) @@ -921,7 +923,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector &Features, HasSM4 = true; } if (Feature == "+strict-align") - HasUnaligned = false; + HasUnalignedAccess = false; + // All predecessor archs are added but select the latest one for ArchKind. if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version) ArchInfo = &llvm::AArch64::ARMV8A; diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 542894c66412dc..12fb50286f7511 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -38,7 +38,6 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool HasSHA2 = false; bool HasSHA3 = false; bool HasSM4 = false; - bool HasUnaligned = true; bool HasFullFP16 = false; bool HasDotProd = false; bool HasFP16FML = false; diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index 55b71557452fa0..877799c66ec4f2 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -509,7 +509,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector &Features, SHA2 = 0; AES = 0; DSP = 0; - Unaligned = 1; + HasUnalignedAccess = true; SoftFloat = false; // Note that SoftFloatABI is initialized in our constructor. HWDiv = 0; @@ -576,7 +576,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector &Features, return false; } } else if (Feature == "+strict-align") { - Unaligned = 0; + HasUnalignedAccess = false; } else if (Feature == "+fp16") { HW_FP |= HW_FP_HP; } else if (Feature == "+fullfp16") { @@ -785,7 +785,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'"); // ACLE 6.4.3 Unaligned access supported in hardware - if (Unaligned) + if (HasUnalignedAccess) Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); // ACLE 6.4.4 LDREX/STREX diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h index 71322a094f5edb..e69adbe754739f 100644 --- a/clang/lib/Basic/Targets/ARM.h +++ b/clang/lib/Basic/Targets/ARM.h @@ -88,8 +88,6 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { LLVM_PREFERRED_TYPE(bool) unsigned DSP : 1; LLVM_PREFERRED_TYPE(bool) - unsigned Unaligned : 1; - LLVM_PREFERRED_TYPE(bool) unsigned DotProd : 1; LLVM_PREFERRED_TYPE(bool) unsigned HasMatMul : 1; diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index 88537989a05129..280bd1d8033cc6 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -285,6 +285,8 @@ bool LoongArchTargetInfo::handleTargetFeatures( HasFeatureLSX = true; else if (Feature == "+lasx") HasFeatureLASX = true; + else if (Feature == "-ual") + HasUnalignedAccess = false; } return true; } diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 3313102492cb8d..68572843f2d748 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -132,6 +132,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArch64TargetInfo : LoongArchTargetInfo(Triple, Opts) { LongWidth = LongAlign = PointerWidth = PointerAlign = 64; IntMaxType = Int64Type = SignedLong; + HasUnalignedAccess = true; resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128"); // TODO: select appropriate ABI. setABI("lp64d"); diff --git a/clang/lib/Basic/Targets/M68k.cpp b/clang/lib/Basic/Targets/M68k.cpp index 1b7e0a7f32c9be..8b8bf97d6f99a1 100644 --- a/clang/lib/Basic/Targets/M68k.cpp +++ b/clang/lib/Basic/Targets/M68k.cpp @@ -127,16 +127,21 @@ bool M68kTargetInfo::hasFeature(StringRef Feature) const { const char *const M68kTargetInfo::GCCRegNames[] = { "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", - "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", + "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", "pc"}; ArrayRef M68kTargetInfo::getGCCRegNames() const { return llvm::ArrayRef(GCCRegNames); } +const TargetInfo::GCCRegAlias M68kTargetInfo::GCCRegAliases[] = { + {{"bp"}, "a5"}, + {{"fp"}, "a6"}, + {{"usp", "ssp", "isp", "a7"}, "sp"}, +}; + ArrayRef M68kTargetInfo::getGCCRegAliases() const { - // No aliases. - return std::nullopt; + return llvm::ArrayRef(GCCRegAliases); } bool M68kTargetInfo::validateAsmConstraint( diff --git a/clang/lib/Basic/Targets/M68k.h b/clang/lib/Basic/Targets/M68k.h index a9c262e62fbad0..7ffa901127e504 100644 --- a/clang/lib/Basic/Targets/M68k.h +++ b/clang/lib/Basic/Targets/M68k.h @@ -25,6 +25,7 @@ namespace targets { class LLVM_LIBRARY_VISIBILITY M68kTargetInfo : public TargetInfo { static const char *const GCCRegNames[]; + static const TargetInfo::GCCRegAlias GCCRegAliases[]; enum CPUKind { CK_Unknown, diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index 23d4e1b598fa1e..c9dcf434c93b0b 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -328,6 +328,8 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { IsMips16 = true; else if (Feature == "+micromips") IsMicromips = true; + else if (Feature == "+mips32r6" || Feature == "+mips64r6") + HasUnalignedAccess = true; else if (Feature == "+dsp") DspRev = std::max(DspRev, DSP1); else if (Feature == "+dspr2") diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..fa2f442e25846d 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -92,6 +92,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); HasStrictFP = true; HasIbm128 = true; + HasUnalignedAccess = true; } // Set the language option for altivec based on our value. diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 3e08b27972fa39..8e302acd51b8ad 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -47,6 +47,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { LongDoubleFormat = &llvm::APFloat::IEEEquad(); DefaultAlignForAttributeAligned = 64; MinGlobalAlign = 16; + HasUnalignedAccess = true; if (Triple.isOSzOS()) { TLSSupported = false; // All vector types are default aligned on an 8-byte boundary, even if the diff --git a/clang/lib/Basic/Targets/VE.h b/clang/lib/Basic/Targets/VE.h index ea9a092cad8090..7e8fdf6096ef23 100644 --- a/clang/lib/Basic/Targets/VE.h +++ b/clang/lib/Basic/Targets/VE.h @@ -40,6 +40,7 @@ class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo { Int64Type = SignedLong; RegParmMax = 8; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + HasUnalignedAccess = true; WCharType = UnsignedInt; WIntType = UnsignedInt; diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index 83b1711f9fdf6a..5568aa28eaefa7 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -84,6 +84,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { SizeType = UnsignedLong; PtrDiffType = SignedLong; IntPtrType = SignedLong; + HasUnalignedAccess = true; } StringRef getABI() const override; diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index d2232c7d5275ab..c14e4d5f433d82 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -188,6 +188,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); AddrSpaceMap = &X86AddrSpaceMap; HasStrictFP = true; + HasUnalignedAccess = true; bool IsWinCOFF = getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 82b30b8d815629..1220c575d1df9f 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -101,20 +101,19 @@ namespace llvm { extern cl::opt PrintPipelinePasses; cl::opt ClRemoveTraps("clang-remove-traps", cl::Optional, - cl::desc("Insert remove-traps pass."), - cl::init(false)); + cl::desc("Insert remove-traps pass.")); // Experiment to move sanitizers earlier. static cl::opt ClSanitizeOnOptimizerEarlyEP( "sanitizer-early-opt-ep", cl::Optional, - cl::desc("Insert sanitizers on OptimizerEarlyEP."), cl::init(false)); + cl::desc("Insert sanitizers on OptimizerEarlyEP.")); extern cl::opt ProfileCorrelate; // Re-link builtin bitcodes after optimization cl::opt ClRelinkBuiltinBitcodePostop( "relink-builtin-bitcode-postop", cl::Optional, - cl::desc("Re-link builtin bitcodes after optimization."), cl::init(false)); + cl::desc("Re-link builtin bitcodes after optimization.")); } // namespace llvm namespace { diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index 56198385de9dcb..d35ce0409d7232 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -197,11 +197,11 @@ namespace { llvm::Value *getScalarRValValueOrNull(RValue RVal) const; /// Converts an rvalue to integer value if needed. - llvm::Value *convertRValueToInt(RValue RVal, bool CastFP = true) const; + llvm::Value *convertRValueToInt(RValue RVal, bool CmpXchg = false) const; RValue ConvertToValueOrAtomic(llvm::Value *IntVal, AggValueSlot ResultSlot, SourceLocation Loc, bool AsValue, - bool CastFP = true) const; + bool CmpXchg = false) const; /// Copy an atomic r-value into atomic-layout memory. void emitCopyIntoMemory(RValue rvalue) const; @@ -264,7 +264,7 @@ namespace { llvm::AtomicOrdering AO, bool IsVolatile); /// Emits atomic load as LLVM instruction. llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile, - bool CastFP = true); + bool CmpXchg = false); /// Emits atomic compare-and-exchange op as a libcall. llvm::Value *EmitAtomicCompareExchangeLibcall( llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr, @@ -1401,13 +1401,26 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr, LVal.getBaseInfo(), TBAAAccessInfo())); } +/// Return true if \param ValTy is a type that should be casted to integer +/// around the atomic memory operation. If \param CmpXchg is true, then the +/// cast of a floating point type is made as that instruction can not have +/// floating point operands. TODO: Allow compare-and-exchange and FP - see +/// comment in AtomicExpandPass.cpp. +static bool shouldCastToInt(llvm::Type *ValTy, bool CmpXchg) { + if (ValTy->isFloatingPointTy()) + return ValTy->isX86_FP80Ty() || CmpXchg; + return !ValTy->isIntegerTy() && !ValTy->isPointerTy(); +} + RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, AggValueSlot ResultSlot, SourceLocation Loc, bool AsValue, - bool CastFP) const { + bool CmpXchg) const { // Try not to in some easy cases. - assert((Val->getType()->isIntegerTy() || Val->getType()->isIEEELikeFPTy()) && - "Expected integer or floating point value"); + assert((Val->getType()->isIntegerTy() || Val->getType()->isPointerTy() || + Val->getType()->isIEEELikeFPTy()) && + "Expected integer, pointer or floating point value when converting " + "result."); if (getEvaluationKind() == TEK_Scalar && (((!LVal.isBitField() || LVal.getBitFieldInfo().Size == ValueSizeInBits) && @@ -1416,13 +1429,12 @@ RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val, auto *ValTy = AsValue ? CGF.ConvertTypeForMem(ValueTy) : getAtomicAddress().getElementType(); - if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) { + if (!shouldCastToInt(ValTy, CmpXchg)) { assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) && "Different integer types."); return RValue::get(CGF.EmitFromMemory(Val, ValueTy)); - } else if (ValTy->isPointerTy()) - return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy)); - else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) + } + if (llvm::CastInst::isBitCastable(Val->getType(), ValTy)) return RValue::get(CGF.Builder.CreateBitCast(Val, ValTy)); } @@ -1459,10 +1471,10 @@ void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, } llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO, - bool IsVolatile, bool CastFP) { + bool IsVolatile, bool CmpXchg) { // Okay, we're doing this natively. Address Addr = getAtomicAddress(); - if (!(Addr.getElementType()->isIEEELikeFPTy() && !CastFP)) + if (shouldCastToInt(Addr.getElementType(), CmpXchg)) Addr = castToAtomicIntPointer(Addr); llvm::LoadInst *Load = CGF.Builder.CreateLoad(Addr, "atomic-load"); Load->setAtomic(AO); @@ -1523,7 +1535,7 @@ RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc, } // Okay, we're doing this natively. - auto *Load = EmitAtomicLoadOp(AO, IsVolatile, /*CastFP=*/false); + auto *Load = EmitAtomicLoadOp(AO, IsVolatile); // If we're ignoring an aggregate return, don't do anything. if (getEvaluationKind() == TEK_Aggregate && ResultSlot.isIgnored()) @@ -1531,8 +1543,7 @@ RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc, // Okay, turn that back into the original value or atomic (for non-simple // lvalues) type. - return ConvertToValueOrAtomic(Load, ResultSlot, Loc, AsValue, - /*CastFP=*/false); + return ConvertToValueOrAtomic(Load, ResultSlot, Loc, AsValue); } /// Emit a load from an l-value of atomic type. Note that the r-value @@ -1601,20 +1612,17 @@ llvm::Value *AtomicInfo::getScalarRValValueOrNull(RValue RVal) const { return nullptr; } -llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal, bool CastFP) const { +llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal, bool CmpXchg) const { // If we've got a scalar value of the right size, try to avoid going // through memory. Floats get casted if needed by AtomicExpandPass. if (llvm::Value *Value = getScalarRValValueOrNull(RVal)) { - if (isa(Value->getType()) || - (!CastFP && Value->getType()->isIEEELikeFPTy())) + if (!shouldCastToInt(Value->getType(), CmpXchg)) return CGF.EmitToMemory(Value, ValueTy); else { llvm::IntegerType *InputIntTy = llvm::IntegerType::get( CGF.getLLVMContext(), LVal.isSimple() ? getValueSizeInBits() : getAtomicSizeInBits()); - if (isa(Value->getType())) - return CGF.Builder.CreatePtrToInt(Value, InputIntTy); - else if (llvm::BitCastInst::isBitCastable(Value->getType(), InputIntTy)) + if (llvm::BitCastInst::isBitCastable(Value->getType(), InputIntTy)) return CGF.Builder.CreateBitCast(Value, InputIntTy); } } @@ -1687,13 +1695,14 @@ std::pair AtomicInfo::EmitAtomicCompareExchange( // If we've got a scalar value of the right size, try to avoid going // through memory. - auto *ExpectedVal = convertRValueToInt(Expected); - auto *DesiredVal = convertRValueToInt(Desired); + auto *ExpectedVal = convertRValueToInt(Expected, /*CmpXchg=*/true); + auto *DesiredVal = convertRValueToInt(Desired, /*CmpXchg=*/true); auto Res = EmitAtomicCompareExchangeOp(ExpectedVal, DesiredVal, Success, Failure, IsWeak); return std::make_pair( ConvertToValueOrAtomic(Res.first, AggValueSlot::ignored(), - SourceLocation(), /*AsValue=*/false), + SourceLocation(), /*AsValue=*/false, + /*CmpXchg=*/true), Res.second); } @@ -1787,7 +1796,7 @@ void AtomicInfo::EmitAtomicUpdateOp( auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); // Do the atomic load. - auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile); + auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile, /*CmpXchg=*/true); // For non-simple lvalues perform compare-and-swap procedure. auto *ContBB = CGF.createBasicBlock("atomic_cont"); auto *ExitBB = CGF.createBasicBlock("atomic_exit"); @@ -1803,7 +1812,8 @@ void AtomicInfo::EmitAtomicUpdateOp( CGF.Builder.CreateStore(PHI, NewAtomicIntAddr); } auto OldRVal = ConvertToValueOrAtomic(PHI, AggValueSlot::ignored(), - SourceLocation(), /*AsValue=*/false); + SourceLocation(), /*AsValue=*/false, + /*CmpXchg=*/true); EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, NewAtomicAddr); auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr); // Try to write new value using cmpxchg operation. @@ -1869,7 +1879,7 @@ void AtomicInfo::EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRVal, auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); // Do the atomic load. - auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile); + auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile, /*CmpXchg=*/true); // For non-simple lvalues perform compare-and-swap procedure. auto *ContBB = CGF.createBasicBlock("atomic_cont"); auto *ExitBB = CGF.createBasicBlock("atomic_exit"); @@ -1969,21 +1979,16 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, } // Okay, we're doing this natively. - llvm::Value *ValToStore = - atomics.convertRValueToInt(rvalue, /*CastFP=*/false); + llvm::Value *ValToStore = atomics.convertRValueToInt(rvalue); // Do the atomic store. Address Addr = atomics.getAtomicAddress(); - bool ShouldCastToInt = true; if (llvm::Value *Value = atomics.getScalarRValValueOrNull(rvalue)) - if (isa(Value->getType()) || - Value->getType()->isIEEELikeFPTy()) - ShouldCastToInt = false; - if (ShouldCastToInt) { - Addr = atomics.castToAtomicIntPointer(Addr); - ValToStore = Builder.CreateIntCast(ValToStore, Addr.getElementType(), - /*isSigned=*/false); - } + if (shouldCastToInt(Value->getType(), /*CmpXchg=*/false)) { + Addr = atomics.castToAtomicIntPointer(Addr); + ValToStore = Builder.CreateIntCast(ValToStore, Addr.getElementType(), + /*isSigned=*/false); + } llvm::StoreInst *store = Builder.CreateStore(ValToStore, Addr); if (AO == llvm::AtomicOrdering::Acquire) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 287e763bad82dd..483f9c26859923 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5835,7 +5835,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, EmitLifetimeEnd(TmpSize, TmpPtr); return Call; } - [[fallthrough]]; + llvm_unreachable("Unexpected enqueue_kernel signature"); } // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block // parameter. @@ -5892,16 +5892,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Name), {NDRange, Kernel, Block})); } - - case Builtin::BI__builtin_hlsl_wave_get_lane_index: { - auto *CI = EmitRuntimeCall(CGM.CreateRuntimeFunction( - llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index", - {}, false, true)); - if (getTarget().getTriple().isSPIRVLogical()) - CI = dyn_cast(addControlledConvergenceToken(CI)); - return RValue::get(CI); - } - case Builtin::BI__builtin_store_half: case Builtin::BI__builtin_store_halff: { Value *Val = EmitScalarExpr(E->getArg(0)); @@ -18317,6 +18307,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/Op0->getType(), Intrinsic::dx_rsqrt, ArrayRef{Op0}, nullptr, "dx.rsqrt"); } + case Builtin::BI__builtin_hlsl_wave_get_lane_index: { + auto *CI = EmitRuntimeCall(CGM.CreateRuntimeFunction( + llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index", + {}, false, true)); + if (getTarget().getTriple().isSPIRVLogical()) + CI = dyn_cast(addControlledConvergenceToken(CI)); + return CI; + } } return nullptr; } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 4a4426d13e7b6b..f12765b826935b 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4720,7 +4720,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, } if (HasAggregateEvalKind && isa(E) && - cast(E)->getCastKind() == CK_LValueToRValue) { + cast(E)->getCastKind() == CK_LValueToRValue && + !type->isArrayParameterType()) { LValue L = EmitLValue(cast(E)->getSubExpr()); assert(L.isSimple()); args.addUncopiedAggregate(L, type); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 691fde8b0d8b82..8c284c332171a1 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3641,6 +3641,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) { case Type::ConstantArray: case Type::VariableArray: case Type::IncompleteArray: + case Type::ArrayParameter: return CreateType(cast(Ty), Unit); case Type::LValueReference: diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 36872c0fedb76e..54432353e7420d 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -56,8 +56,7 @@ using namespace CodeGen; // Experiment to make sanitizers easier to debug static llvm::cl::opt ClSanitizeDebugDeoptimization( "ubsan-unique-traps", llvm::cl::Optional, - llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check"), - llvm::cl::init(false)); + llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check")); //===--------------------------------------------------------------------===// // Miscellaneous Helper Methods @@ -5190,6 +5189,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { case CK_IntegralToFixedPoint: case CK_MatrixCast: case CK_HLSLVectorTruncation: + case CK_HLSLArrayRValue: return EmitUnsupportedLValue(E, "unexpected cast lvalue"); case CK_Dependent: diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 143855aa84ca3f..1b9287ea239347 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -883,6 +883,9 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { [[fallthrough]]; + case CK_HLSLArrayRValue: + Visit(E->getSubExpr()); + break; case CK_NoOp: case CK_UserDefinedConversion: @@ -1524,6 +1527,7 @@ static bool castPreservesZero(const CastExpr *CE) { case CK_LValueToRValue: case CK_LValueToRValueBitCast: case CK_UncheckedDerivedToBase: + case CK_HLSLArrayRValue: return false; } llvm_unreachable("Unhandled clang::CastKind enum"); diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index c3774d0cb75edc..a793b214645cb3 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -616,6 +616,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, case CK_IntegralToFixedPoint: case CK_MatrixCast: case CK_HLSLVectorTruncation: + case CK_HLSLArrayRValue: llvm_unreachable("invalid cast kind for complex value"); case CK_FloatingRealToComplex: diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 36d7493d9a6baf..9f1b06eebf9ed0 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1226,6 +1226,7 @@ class ConstExprEmitter : case CK_ZeroToOCLOpaqueType: case CK_MatrixCast: case CK_HLSLVectorTruncation: + case CK_HLSLArrayRValue: return nullptr; } llvm_unreachable("Invalid CastKind"); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 83247aa48f8609..397b4977acc3e9 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2329,6 +2329,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { case CK_FloatingComplexToIntegralComplex: case CK_ConstructorConversion: case CK_ToUnion: + case CK_HLSLArrayRValue: llvm_unreachable("scalar cast to non-scalar value"); case CK_LValueToRValue: diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index 7822903b89ce47..634a55fec5182e 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -47,8 +47,10 @@ namespace { /// [i8 x 3] instead of i24. The function clipTailPadding does this. /// C++ examples that require clipping: /// struct { int a : 24; char b; }; // a must be clipped, b goes at offset 3 -/// struct A { int a : 24; }; // a must be clipped because a struct like B -// could exist: struct B : A { char b; }; // b goes at offset 3 +/// struct A { int a : 24; ~A(); }; // a must be clipped because: +/// struct B : A { char b; }; // b goes at offset 3 +/// * The allocation of bitfield access units is described in more detail in +/// CGRecordLowering::accumulateBitFields. /// * Clang ignores 0 sized bitfields and 0 sized bases but *not* zero sized /// fields. The existing asserts suggest that LLVM assumes that *every* field /// has an underlying storage type. Therefore empty structures containing @@ -183,17 +185,21 @@ struct CGRecordLowering { /// Lowers an ASTRecordLayout to a llvm type. void lower(bool NonVirtualBaseType); void lowerUnion(bool isNoUniqueAddress); - void accumulateFields(); - void accumulateBitFields(RecordDecl::field_iterator Field, - RecordDecl::field_iterator FieldEnd); + void accumulateFields(bool isNonVirtualBaseType); + RecordDecl::field_iterator + accumulateBitFields(bool isNonVirtualBaseType, + RecordDecl::field_iterator Field, + RecordDecl::field_iterator FieldEnd); void computeVolatileBitfields(); void accumulateBases(); void accumulateVPtrs(); void accumulateVBases(); /// Recursively searches all of the bases to find out if a vbase is /// not the primary vbase of some base class. - bool hasOwnStorage(const CXXRecordDecl *Decl, const CXXRecordDecl *Query); + bool hasOwnStorage(const CXXRecordDecl *Decl, + const CXXRecordDecl *Query) const; void calculateZeroInit(); + CharUnits calculateTailClippingOffset(bool isNonVirtualBaseType) const; /// Lowers bitfield storage types to I8 arrays for bitfields with tail /// padding that is or can potentially be used. void clipTailPadding(); @@ -284,7 +290,7 @@ void CGRecordLowering::lower(bool NVBaseType) { computeVolatileBitfields(); return; } - accumulateFields(); + accumulateFields(NVBaseType); // RD implies C++. if (RD) { accumulateVPtrs(); @@ -375,16 +381,18 @@ void CGRecordLowering::lowerUnion(bool isNoUniqueAddress) { Packed = true; } -void CGRecordLowering::accumulateFields() { +void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) { for (RecordDecl::field_iterator Field = D->field_begin(), FieldEnd = D->field_end(); - Field != FieldEnd;) { + Field != FieldEnd;) { if (Field->isBitField()) { - RecordDecl::field_iterator Start = Field; - // Iterate to gather the list of bitfields. - for (++Field; Field != FieldEnd && Field->isBitField(); ++Field); - accumulateBitFields(Start, Field); - } else if (!Field->isZeroSize(Context)) { + Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd); + assert((Field == FieldEnd || !Field->isBitField()) && + "Failed to accumulate all the bitfields"); + } else if (Field->isZeroSize(Context)) { + // Empty fields have no storage. + ++Field; + } else { // Use base subobject layout for the potentially-overlapping field, // as it is done in RecordLayoutBuilder Members.push_back(MemberInfo( @@ -394,33 +402,36 @@ void CGRecordLowering::accumulateFields() { : getStorageType(*Field), *Field)); ++Field; - } else { - ++Field; } } } -void -CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field, +// Create members for bitfields. Field is a bitfield, and FieldEnd is the end +// iterator of the record. Return the first non-bitfield encountered. We need +// to know whether this is the base or complete layout, as virtual bases could +// affect the upper bound of bitfield access unit allocation. +RecordDecl::field_iterator +CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType, + RecordDecl::field_iterator Field, RecordDecl::field_iterator FieldEnd) { - // Run stores the first element of the current run of bitfields. FieldEnd is - // used as a special value to note that we don't have a current run. A - // bitfield run is a contiguous collection of bitfields that can be stored in - // the same storage block. Zero-sized bitfields and bitfields that would - // cross an alignment boundary break a run and start a new one. - RecordDecl::field_iterator Run = FieldEnd; - // Tail is the offset of the first bit off the end of the current run. It's - // used to determine if the ASTRecordLayout is treating these two bitfields as - // contiguous. StartBitOffset is offset of the beginning of the Run. - uint64_t StartBitOffset, Tail = 0; if (isDiscreteBitFieldABI()) { - for (; Field != FieldEnd; ++Field) { - uint64_t BitOffset = getFieldBitOffset(*Field); + // Run stores the first element of the current run of bitfields. FieldEnd is + // used as a special value to note that we don't have a current run. A + // bitfield run is a contiguous collection of bitfields that can be stored + // in the same storage block. Zero-sized bitfields and bitfields that would + // cross an alignment boundary break a run and start a new one. + RecordDecl::field_iterator Run = FieldEnd; + // Tail is the offset of the first bit off the end of the current run. It's + // used to determine if the ASTRecordLayout is treating these two bitfields + // as contiguous. StartBitOffset is offset of the beginning of the Run. + uint64_t StartBitOffset, Tail = 0; + for (; Field != FieldEnd && Field->isBitField(); ++Field) { // Zero-width bitfields end runs. if (Field->isZeroLengthBitField(Context)) { Run = FieldEnd; continue; } + uint64_t BitOffset = getFieldBitOffset(*Field); llvm::Type *Type = Types.ConvertTypeForMem(Field->getType(), /*ForBitField=*/true); // If we don't have a run yet, or don't live within the previous run's @@ -439,82 +450,256 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field, Members.push_back(MemberInfo(bitsToCharUnits(StartBitOffset), MemberInfo::Field, nullptr, *Field)); } - return; + return Field; } - // Check if OffsetInRecord (the size in bits of the current run) is better - // as a single field run. When OffsetInRecord has legal integer width, and - // its bitfield offset is naturally aligned, it is better to make the - // bitfield a separate storage component so as it can be accessed directly - // with lower cost. - auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord, - uint64_t StartBitOffset) { - if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses) - return false; - if (OffsetInRecord < 8 || !llvm::isPowerOf2_64(OffsetInRecord) || - !DataLayout.fitsInLegalInteger(OffsetInRecord)) - return false; - // Make sure StartBitOffset is naturally aligned if it is treated as an - // IType integer. - if (StartBitOffset % - Context.toBits(getAlignment(getIntNType(OffsetInRecord))) != - 0) - return false; - return true; - }; + // The SysV ABI can overlap bitfield storage units with both other bitfield + // storage units /and/ other non-bitfield data members. Accessing a sequence + // of bitfields mustn't interfere with adjacent non-bitfields -- they're + // permitted to be accessed in separate threads for instance. + + // We split runs of bit-fields into a sequence of "access units". When we emit + // a load or store of a bit-field, we'll load/store the entire containing + // access unit. As mentioned, the standard requires that these loads and + // stores must not interfere with accesses to other memory locations, and it + // defines the bit-field's memory location as the current run of + // non-zero-width bit-fields. So an access unit must never overlap with + // non-bit-field storage or cross a zero-width bit-field. Otherwise, we're + // free to draw the lines as we see fit. + + // Drawing these lines well can be complicated. LLVM generally can't modify a + // program to access memory that it didn't before, so using very narrow access + // units can prevent the compiler from using optimal access patterns. For + // example, suppose a run of bit-fields occupies four bytes in a struct. If we + // split that into four 1-byte access units, then a sequence of assignments + // that doesn't touch all four bytes may have to be emitted with multiple + // 8-bit stores instead of a single 32-bit store. On the other hand, if we use + // very wide access units, we may find ourselves emitting accesses to + // bit-fields we didn't really need to touch, just because LLVM was unable to + // clean up after us. + + // It is desirable to have access units be aligned powers of 2 no larger than + // a register. (On non-strict alignment ISAs, the alignment requirement can be + // dropped.) A three byte access unit will be accessed using 2-byte and 1-byte + // accesses and bit manipulation. If no bitfield straddles across the two + // separate accesses, it is better to have separate 2-byte and 1-byte access + // units, as then LLVM will not generate unnecessary memory accesses, or bit + // manipulation. Similarly, on a strict-alignment architecture, it is better + // to keep access-units naturally aligned, to avoid similar bit + // manipulation synthesizing larger unaligned accesses. + + // Bitfields that share parts of a single byte are, of necessity, placed in + // the same access unit. That unit will encompass a consecutive run where + // adjacent bitfields share parts of a byte. (The first bitfield of such an + // access unit will start at the beginning of a byte.) + + // We then try and accumulate adjacent access units when the combined unit is + // naturally sized, no larger than a register, and (on a strict alignment + // ISA), naturally aligned. Note that this requires lookahead to one or more + // subsequent access units. For instance, consider a 2-byte access-unit + // followed by 2 1-byte units. We can merge that into a 4-byte access-unit, + // but we would not want to merge a 2-byte followed by a single 1-byte (and no + // available tail padding). We keep track of the best access unit seen so far, + // and use that when we determine we cannot accumulate any more. Then we start + // again at the bitfield following that best one. + + // The accumulation is also prevented when: + // *) it would cross a character-aigned zero-width bitfield, or + // *) fine-grained bitfield access option is in effect. + + CharUnits RegSize = + bitsToCharUnits(Context.getTargetInfo().getRegisterWidth()); + unsigned CharBits = Context.getCharWidth(); + + // Limit of useable tail padding at end of the record. Computed lazily and + // cached here. + CharUnits ScissorOffset = CharUnits::Zero(); + + // Data about the start of the span we're accumulating to create an access + // unit from. Begin is the first bitfield of the span. If Begin is FieldEnd, + // we've not got a current span. The span starts at the BeginOffset character + // boundary. BitSizeSinceBegin is the size (in bits) of the span -- this might + // include padding when we've advanced to a subsequent bitfield run. + RecordDecl::field_iterator Begin = FieldEnd; + CharUnits BeginOffset; + uint64_t BitSizeSinceBegin; + + // The (non-inclusive) end of the largest acceptable access unit we've found + // since Begin. If this is Begin, we're gathering the initial set of bitfields + // of a new span. BestEndOffset is the end of that acceptable access unit -- + // it might extend beyond the last character of the bitfield run, using + // available padding characters. + RecordDecl::field_iterator BestEnd = Begin; + CharUnits BestEndOffset; - // The start field is better as a single field run. - bool StartFieldAsSingleRun = false; for (;;) { - // Check to see if we need to start a new run. - if (Run == FieldEnd) { - // If we're out of fields, return. - if (Field == FieldEnd) + // AtAlignedBoundary is true iff Field is the (potential) start of a new + // span (or the end of the bitfields). When true, LimitOffset is the + // character offset of that span and Barrier indicates whether the new + // span cannot be merged into the current one. + bool AtAlignedBoundary = false; + bool Barrier = false; + + if (Field != FieldEnd && Field->isBitField()) { + uint64_t BitOffset = getFieldBitOffset(*Field); + if (Begin == FieldEnd) { + // Beginning a new span. + Begin = Field; + BestEnd = Begin; + + assert((BitOffset % CharBits) == 0 && "Not at start of char"); + BeginOffset = bitsToCharUnits(BitOffset); + BitSizeSinceBegin = 0; + } else if ((BitOffset % CharBits) != 0) { + // Bitfield occupies the same character as previous bitfield, it must be + // part of the same span. This can include zero-length bitfields, should + // the target not align them to character boundaries. Such non-alignment + // is at variance with the standards, which require zero-length + // bitfields be a barrier between access units. But of course we can't + // achieve that in the middle of a character. + assert(BitOffset == Context.toBits(BeginOffset) + BitSizeSinceBegin && + "Concatenating non-contiguous bitfields"); + } else { + // Bitfield potentially begins a new span. This includes zero-length + // bitfields on non-aligning targets that lie at character boundaries + // (those are barriers to merging). + if (Field->isZeroLengthBitField(Context)) + Barrier = true; + AtAlignedBoundary = true; + } + } else { + // We've reached the end of the bitfield run. Either we're done, or this + // is a barrier for the current span. + if (Begin == FieldEnd) break; - // Any non-zero-length bitfield can start a new run. - if (!Field->isZeroLengthBitField(Context)) { - Run = Field; - StartBitOffset = getFieldBitOffset(*Field); - Tail = StartBitOffset + Field->getBitWidthValue(Context); - StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Tail - StartBitOffset, - StartBitOffset); + + Barrier = true; + AtAlignedBoundary = true; + } + + // InstallBest indicates whether we should create an access unit for the + // current best span: fields [Begin, BestEnd) occupying characters + // [BeginOffset, BestEndOffset). + bool InstallBest = false; + if (AtAlignedBoundary) { + // Field is the start of a new span or the end of the bitfields. The + // just-seen span now extends to BitSizeSinceBegin. + + // Determine if we can accumulate that just-seen span into the current + // accumulation. + CharUnits AccessSize = bitsToCharUnits(BitSizeSinceBegin + CharBits - 1); + if (BestEnd == Begin) { + // This is the initial run at the start of a new span. By definition, + // this is the best seen so far. + BestEnd = Field; + BestEndOffset = BeginOffset + AccessSize; + if (Types.getCodeGenOpts().FineGrainedBitfieldAccesses) + // Fine-grained access, so no merging of spans. + InstallBest = true; + else if (!BitSizeSinceBegin) + // A zero-sized initial span -- this will install nothing and reset + // for another. + InstallBest = true; + } else if (AccessSize > RegSize) + // Accumulating the just-seen span would create a multi-register access + // unit, which would increase register pressure. + InstallBest = true; + + if (!InstallBest) { + // Determine if accumulating the just-seen span will create an expensive + // access unit or not. + llvm::Type *Type = getIntNType(Context.toBits(AccessSize)); + if (!Context.getTargetInfo().hasCheapUnalignedBitFieldAccess()) { + // Unaligned accesses are expensive. Only accumulate if the new unit + // is naturally aligned. Otherwise install the best we have, which is + // either the initial access unit (can't do better), or a naturally + // aligned accumulation (since we would have already installed it if + // it wasn't naturally aligned). + CharUnits Align = getAlignment(Type); + if (Align > Layout.getAlignment()) + // The alignment required is greater than the containing structure + // itself. + InstallBest = true; + else if (!BeginOffset.isMultipleOf(Align)) + // The access unit is not at a naturally aligned offset within the + // structure. + InstallBest = true; + } + + if (!InstallBest) { + // Find the next used storage offset to determine what the limit of + // the current span is. That's either the offset of the next field + // with storage (which might be Field itself) or the end of the + // non-reusable tail padding. + CharUnits LimitOffset; + for (auto Probe = Field; Probe != FieldEnd; ++Probe) + if (!Probe->isZeroSize(Context)) { + // A member with storage sets the limit. + assert((getFieldBitOffset(*Probe) % CharBits) == 0 && + "Next storage is not byte-aligned"); + LimitOffset = bitsToCharUnits(getFieldBitOffset(*Probe)); + goto FoundLimit; + } + // We reached the end of the fields, determine the bounds of useable + // tail padding. As this can be complex for C++, we cache the result. + if (ScissorOffset.isZero()) { + ScissorOffset = calculateTailClippingOffset(isNonVirtualBaseType); + assert(!ScissorOffset.isZero() && "Tail clipping at zero"); + } + + LimitOffset = ScissorOffset; + FoundLimit:; + + CharUnits TypeSize = getSize(Type); + if (BeginOffset + TypeSize <= LimitOffset) { + // There is space before LimitOffset to create a naturally-sized + // access unit. + BestEndOffset = BeginOffset + TypeSize; + BestEnd = Field; + } + + if (Barrier) + // The next field is a barrier that we cannot merge across. + InstallBest = true; + else + // Otherwise, we're not installing. Update the bit size + // of the current span to go all the way to LimitOffset, which is + // the (aligned) offset of next bitfield to consider. + BitSizeSinceBegin = Context.toBits(LimitOffset - BeginOffset); + } } - ++Field; - continue; } - // If the start field of a new run is better as a single run, or - // if current field (or consecutive fields) is better as a single run, or - // if current field has zero width bitfield and either - // UseZeroLengthBitfieldAlignment or UseBitFieldTypeAlignment is set to - // true, or - // if the offset of current field is inconsistent with the offset of - // previous field plus its offset, - // skip the block below and go ahead to emit the storage. - // Otherwise, try to add bitfields to the run. - if (!StartFieldAsSingleRun && Field != FieldEnd && - !IsBetterAsSingleFieldRun(Tail - StartBitOffset, StartBitOffset) && - (!Field->isZeroLengthBitField(Context) || - (!Context.getTargetInfo().useZeroLengthBitfieldAlignment() && - !Context.getTargetInfo().useBitFieldTypeAlignment())) && - Tail == getFieldBitOffset(*Field)) { - Tail += Field->getBitWidthValue(Context); + if (InstallBest) { + assert((Field == FieldEnd || !Field->isBitField() || + (getFieldBitOffset(*Field) % CharBits) == 0) && + "Installing but not at an aligned bitfield or limit"); + CharUnits AccessSize = BestEndOffset - BeginOffset; + if (!AccessSize.isZero()) { + // Add the storage member for the access unit to the record. The + // bitfields get the offset of their storage but come afterward and + // remain there after a stable sort. + llvm::Type *Type = getIntNType(Context.toBits(AccessSize)); + Members.push_back(StorageInfo(BeginOffset, Type)); + for (; Begin != BestEnd; ++Begin) + if (!Begin->isZeroLengthBitField(Context)) + Members.push_back( + MemberInfo(BeginOffset, MemberInfo::Field, nullptr, *Begin)); + } + // Reset to start a new span. + Field = BestEnd; + Begin = FieldEnd; + } else { + assert(Field != FieldEnd && Field->isBitField() && + "Accumulating past end of bitfields"); + assert(!Barrier && "Accumulating across barrier"); + // Accumulate this bitfield into the current (potential) span. + BitSizeSinceBegin += Field->getBitWidthValue(Context); ++Field; - continue; } - - // We've hit a break-point in the run and need to emit a storage field. - llvm::Type *Type = getIntNType(Tail - StartBitOffset); - // Add the storage member to the record and set the bitfield info for all of - // the bitfields in the run. Bitfields get the offset of their storage but - // come afterward and remain there after a stable sort. - Members.push_back(StorageInfo(bitsToCharUnits(StartBitOffset), Type)); - for (; Run != Field; ++Run) - Members.push_back(MemberInfo(bitsToCharUnits(StartBitOffset), - MemberInfo::Field, nullptr, *Run)); - Run = FieldEnd; - StartFieldAsSingleRun = false; } + + return Field; } void CGRecordLowering::accumulateBases() { @@ -667,13 +852,17 @@ void CGRecordLowering::accumulateVPtrs() { llvm::PointerType::getUnqual(Types.getLLVMContext()))); } -void CGRecordLowering::accumulateVBases() { +CharUnits +CGRecordLowering::calculateTailClippingOffset(bool isNonVirtualBaseType) const { + if (!RD) + return Layout.getDataSize(); + CharUnits ScissorOffset = Layout.getNonVirtualSize(); // In the itanium ABI, it's possible to place a vbase at a dsize that is // smaller than the nvsize. Here we check to see if such a base is placed // before the nvsize and set the scissor offset to that, instead of the // nvsize. - if (isOverlappingVBaseABI()) + if (!isNonVirtualBaseType && isOverlappingVBaseABI()) for (const auto &Base : RD->vbases()) { const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); if (BaseDecl->isEmpty()) @@ -685,8 +874,13 @@ void CGRecordLowering::accumulateVBases() { ScissorOffset = std::min(ScissorOffset, Layout.getVBaseClassOffset(BaseDecl)); } - Members.push_back(MemberInfo(ScissorOffset, MemberInfo::Scissor, nullptr, - RD)); + + return ScissorOffset; +} + +void CGRecordLowering::accumulateVBases() { + Members.push_back(MemberInfo(calculateTailClippingOffset(false), + MemberInfo::Scissor, nullptr, RD)); for (const auto &Base : RD->vbases()) { const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); if (BaseDecl->isEmpty()) @@ -711,7 +905,7 @@ void CGRecordLowering::accumulateVBases() { } bool CGRecordLowering::hasOwnStorage(const CXXRecordDecl *Decl, - const CXXRecordDecl *Query) { + const CXXRecordDecl *Query) const { const ASTRecordLayout &DeclLayout = Context.getASTRecordLayout(Decl); if (DeclLayout.isPrimaryBaseVirtual() && DeclLayout.getPrimaryBase() == Query) return false; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index fa3f2972458971..6474d6c8c1d1e4 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -276,6 +276,7 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) { case Type::Record: case Type::ObjCObject: case Type::ObjCInterface: + case Type::ArrayParameter: return TEK_Aggregate; // We operate on atomic values according to their underlying type. @@ -2362,6 +2363,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { type = cast(ty)->getPointeeType(); break; + case Type::ArrayParameter: case Type::ConstantArray: case Type::IncompleteArray: // Losing element qualification here is fine. diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index afadc29ab1b027..1568b6e6275b9d 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -590,6 +590,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { ResultType = llvm::ArrayType::get(ResultType, 0); break; } + case Type::ArrayParameter: case Type::ConstantArray: { const ConstantArrayType *A = cast(Ty); llvm::Type *EltTy = ConvertTypeForMem(A->getElementType()); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index fd71317572f0c9..18acf7784f714b 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3584,6 +3584,9 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) { case Type::Pipe: llvm_unreachable("Pipe types shouldn't get here"); + case Type::ArrayParameter: + llvm_unreachable("Array Parameter types should not get here."); + case Type::Builtin: case Type::BitInt: // GCC treats vector and complex types as fundamental types. @@ -3868,6 +3871,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( case Type::ConstantArray: case Type::IncompleteArray: case Type::VariableArray: + case Type::ArrayParameter: // Itanium C++ ABI 2.9.5p5: // abi::__array_type_info adds no data members to std::type_info. break; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 7a53764364ce4d..1a0f5f27eda2fc 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -5814,19 +5814,9 @@ static const char *GetModuleOutputPath(Compilation &C, const JobAction &JA, (C.getArgs().hasArg(options::OPT_fmodule_output) || C.getArgs().hasArg(options::OPT_fmodule_output_EQ))); - if (Arg *ModuleOutputEQ = - C.getArgs().getLastArg(options::OPT_fmodule_output_EQ)) - return C.addResultFile(ModuleOutputEQ->getValue(), &JA); + SmallString<256> OutputPath = + tools::getCXX20NamedModuleOutputPath(C.getArgs(), BaseInput); - SmallString<64> OutputPath; - Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o); - if (FinalOutput && C.getArgs().hasArg(options::OPT_c)) - OutputPath = FinalOutput->getValue(); - else - OutputPath = BaseInput; - - const char *Extension = types::getTypeTempSuffix(JA.getType()); - llvm::sys::path::replace_extension(OutputPath, Extension); return C.addResultFile(C.getArgs().MakeArgString(OutputPath.c_str()), &JA); } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3bcacff7724c7d..b03ac6018d2b80 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3839,6 +3839,24 @@ bool Driver::getDefaultModuleCachePath(SmallVectorImpl &Result) { return false; } +llvm::SmallString<256> +clang::driver::tools::getCXX20NamedModuleOutputPath(const ArgList &Args, + const char *BaseInput) { + if (Arg *ModuleOutputEQ = Args.getLastArg(options::OPT_fmodule_output_EQ)) + return StringRef(ModuleOutputEQ->getValue()); + + SmallString<256> OutputPath; + if (Arg *FinalOutput = Args.getLastArg(options::OPT_o); + FinalOutput && Args.hasArg(options::OPT_c)) + OutputPath = FinalOutput->getValue(); + else + OutputPath = BaseInput; + + const char *Extension = types::getTypeTempSuffix(types::TY_ModuleFile); + llvm::sys::path::replace_extension(OutputPath, Extension); + return OutputPath; +} + static bool RenderModulesOptions(Compilation &C, const Driver &D, const ArgList &Args, const InputInfo &Input, const InputInfo &Output, bool HaveStd20, diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h index 0f503c4bd1c4fe..18f6c5ed06a59a 100644 --- a/clang/lib/Driver/ToolChains/Clang.h +++ b/clang/lib/Driver/ToolChains/Clang.h @@ -193,6 +193,21 @@ DwarfFissionKind getDebugFissionKind(const Driver &D, const llvm::opt::ArgList &Args, llvm::opt::Arg *&Arg); +// Calculate the output path of the module file when compiling a module unit +// with the `-fmodule-output` option or `-fmodule-output=` option specified. +// The behavior is: +// - If `-fmodule-output=` is specfied, then the module file is +// writing to the value. +// - Otherwise if the output object file of the module unit is specified, the +// output path +// of the module file should be the same with the output object file except +// the corresponding suffix. This requires both `-o` and `-c` are specified. +// - Otherwise, the output path of the module file will be the same with the +// input with the corresponding suffix. +llvm::SmallString<256> +getCXX20NamedModuleOutputPath(const llvm::opt::ArgList &Args, + const char *BaseInput); + } // end namespace tools } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index ace4fb99581e38..62a53b85ce098b 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1075,14 +1075,14 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, /// Adds the '-lcgpu' and '-lmgpu' libraries to the compilation to include the /// LLVM C library for GPUs. -static void addOpenMPDeviceLibC(const ToolChain &TC, const ArgList &Args, +static void addOpenMPDeviceLibC(const Compilation &C, const ArgList &Args, ArgStringList &CmdArgs) { if (Args.hasArg(options::OPT_nogpulib) || Args.hasArg(options::OPT_nolibc)) return; // Check the resource directory for the LLVM libc GPU declarations. If it's // found we can assume that LLVM was built with support for the GPU libc. - SmallString<256> LibCDecls(TC.getDriver().ResourceDir); + SmallString<256> LibCDecls(C.getDriver().ResourceDir); llvm::sys::path::append(LibCDecls, "include", "llvm_libc_wrappers", "llvm-libc-decls"); bool HasLibC = llvm::sys::fs::exists(LibCDecls) && @@ -1090,38 +1090,23 @@ static void addOpenMPDeviceLibC(const ToolChain &TC, const ArgList &Args, if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC)) return; - // We don't have access to the offloading toolchains here, so determine from - // the arguments if we have any active NVPTX or AMDGPU toolchains. - llvm::DenseSet Libraries; - if (const Arg *Targets = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) { - if (llvm::any_of(Targets->getValues(), - [](auto S) { return llvm::Triple(S).isAMDGPU(); })) { - Libraries.insert("-lcgpu-amdgpu"); - Libraries.insert("-lmgpu-amdgpu"); - } - if (llvm::any_of(Targets->getValues(), - [](auto S) { return llvm::Triple(S).isNVPTX(); })) { - Libraries.insert("-lcgpu-nvptx"); - Libraries.insert("-lmgpu-nvptx"); - } - } + SmallVector ToolChains; + auto TCRange = C.getOffloadToolChains(Action::OFK_OpenMP); + for (auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI) + ToolChains.push_back(TI->second); - for (StringRef Arch : Args.getAllArgValues(options::OPT_offload_arch_EQ)) { - if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) { - return IsAMDGpuArch(StringToCudaArch(Str)); - })) { - Libraries.insert("-lcgpu-amdgpu"); - Libraries.insert("-lmgpu-amdgpu"); - } - if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) { - return IsNVIDIAGpuArch(StringToCudaArch(Str)); - })) { - Libraries.insert("-lcgpu-nvptx"); - Libraries.insert("-lmgpu-nvptx"); - } + if (llvm::any_of(ToolChains, [](const ToolChain *TC) { + return TC->getTriple().isAMDGPU(); + })) { + CmdArgs.push_back("-lcgpu-amdgpu"); + CmdArgs.push_back("-lmgpu-amdgpu"); + } + if (llvm::any_of(ToolChains, [](const ToolChain *TC) { + return TC->getTriple().isNVPTX(); + })) { + CmdArgs.push_back("-lcgpu-nvptx"); + CmdArgs.push_back("-lmgpu-nvptx"); } - - llvm::append_range(CmdArgs, Libraries); } void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC, @@ -1153,9 +1138,10 @@ void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args, } } -bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, - const ArgList &Args, bool ForceStaticHostRuntime, - bool IsOffloadingHost, bool GompNeedsRT) { +bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs, + const ToolChain &TC, const ArgList &Args, + bool ForceStaticHostRuntime, bool IsOffloadingHost, + bool GompNeedsRT) { if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, options::OPT_fno_openmp, false)) return false; @@ -1196,7 +1182,7 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, CmdArgs.push_back("-lomptarget.devicertl"); if (IsOffloadingHost) - addOpenMPDeviceLibC(TC, Args, CmdArgs); + addOpenMPDeviceLibC(C, Args, CmdArgs); addArchSpecificRPath(TC, Args, CmdArgs); addOpenMPRuntimeLibraryPath(TC, Args, CmdArgs); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index bb37be4bd6ea05..5581905db31144 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -111,8 +111,8 @@ void addOpenMPRuntimeLibraryPath(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs); /// Returns true, if an OpenMP runtime has been added. -bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC, - const llvm::opt::ArgList &Args, +bool addOpenMPRuntime(const Compilation &C, llvm::opt::ArgStringList &CmdArgs, + const ToolChain &TC, const llvm::opt::ArgList &Args, bool ForceStaticHostRuntime = false, bool IsOffloadingHost = false, bool GompNeedsRT = false); diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index c7682c7f1d3379..caf6c4a444fdce 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -686,7 +686,7 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, } if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) - addOpenMPRuntime(CmdArgs, getToolChain(), Args); + addOpenMPRuntime(C, CmdArgs, getToolChain(), Args); if (isObjCRuntimeLinked(Args) && !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { diff --git a/clang/lib/Driver/ToolChains/DragonFly.cpp b/clang/lib/Driver/ToolChains/DragonFly.cpp index b59a172bd6ae86..1dbc46763c1156 100644 --- a/clang/lib/Driver/ToolChains/DragonFly.cpp +++ b/clang/lib/Driver/ToolChains/DragonFly.cpp @@ -136,7 +136,7 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Use the static OpenMP runtime with -static-openmp bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static; - addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP); + addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP); if (D.CCCIsCXX()) { if (ToolChain.ShouldLinkCXXStdlib(Args)) diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp index c5757ddebb0f3e..a8ee6540001ee4 100644 --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -295,7 +295,7 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Use the static OpenMP runtime with -static-openmp bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Args.hasArg(options::OPT_static); - addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP); + addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP); if (D.CCCIsCXX()) { if (ToolChain.ShouldLinkCXXStdlib(Args)) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index a9c9d2475809d7..dedbfac6cb25d2 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -598,7 +598,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // FIXME: Only pass GompNeedsRT = true for platforms with libgomp that // require librt. Most modern Linux platforms do, but some may not. - if (addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP, + if (addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP, JA.isHostOffloading(Action::OFK_OpenMP), /* GompNeedsRT= */ true)) // OpenMP runtimes implies pthreads when using the GNU toolchain. diff --git a/clang/lib/Driver/ToolChains/Haiku.cpp b/clang/lib/Driver/ToolChains/Haiku.cpp index 30464e2229e65b..346652a7e4bd8e 100644 --- a/clang/lib/Driver/ToolChains/Haiku.cpp +++ b/clang/lib/Driver/ToolChains/Haiku.cpp @@ -107,7 +107,7 @@ void haiku::Linker::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_r)) { // Use the static OpenMP runtime with -static-openmp bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static; - addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP); + addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP); if (D.CCCIsCXX() && ToolChain.ShouldLinkCXXStdlib(Args)) ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index dc534a33e6d0ef..fbf2f45b543844 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -79,6 +79,11 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back( Args.MakeArgString(std::string("-out:") + Output.getFilename())); + if (Args.hasArg(options::OPT_marm64x)) + CmdArgs.push_back("-machine:arm64x"); + else if (TC.getTriple().isWindowsArm64EC()) + CmdArgs.push_back("-machine:arm64ec"); + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) { CmdArgs.push_back("-defaultlib:libcmt"); @@ -1017,4 +1022,7 @@ void MSVCToolChain::addClangTargetOptions( if (DriverArgs.hasFlag(options::OPT_fno_rtti, options::OPT_frtti, /*Default=*/false)) CC1Args.push_back("-D_HAS_STATIC_RTTI=0"); + + if (Arg *A = DriverArgs.getLastArgNoClaim(options::OPT_marm64x)) + A->ignoreTargetSpecific(); } diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp index 0eec8fddabd5db..d54f2288294949 100644 --- a/clang/lib/Driver/ToolChains/NetBSD.cpp +++ b/clang/lib/Driver/ToolChains/NetBSD.cpp @@ -311,7 +311,7 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_r)) { // Use the static OpenMP runtime with -static-openmp bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static; - addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP); + addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP); if (D.CCCIsCXX()) { if (ToolChain.ShouldLinkCXXStdlib(Args)) diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp index 6da6728585df93..e20d9fb1cfc417 100644 --- a/clang/lib/Driver/ToolChains/OpenBSD.cpp +++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp @@ -221,7 +221,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_r)) { // Use the static OpenMP runtime with -static-openmp bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static; - addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP); + addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP); if (D.CCCIsCXX()) { if (ToolChain.ShouldLinkCXXStdlib(Args)) diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index 5d7f0ae2a392a6..7126e018ca5b6f 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -211,7 +211,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, // Use the static OpenMP runtime with -static-openmp bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Args.hasArg(options::OPT_static); - addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP); + addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP); if (D.CCCIsCXX()) { if (ToolChain.ShouldLinkCXXStdlib(Args)) diff --git a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp index 22f2c47e1d6a13..81797c8c4dc75a 100644 --- a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp +++ b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp @@ -1000,6 +1000,7 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg, case CK_LValueToRValue: case CK_NoOp: case CK_UserDefinedConversion: + case CK_HLSLArrayRValue: break; case CK_IntegralCast: { diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 80a0a498dc4001..22b98e07c2c890 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -14,14 +14,11 @@ #include "clang/ExtractAPI/DeclarationFragments.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" -#include "clang/AST/QualTypeNames.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" -#include "clang/Basic/OperatorKinds.h" #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" #include "clang/Index/USRGeneration.h" #include "llvm/ADT/StringSwitch.h" -#include using namespace clang::extractapi; using namespace llvm; @@ -535,9 +532,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) { getFragmentsForType(T, Var->getASTContext(), After); if (StringRef(ArgumentFragment.begin()->Spelling) .starts_with("type-parameter")) { - std::string ProperArgName = getNameForTemplateArgument( - Var->getDescribedVarTemplate()->getTemplateParameters()->asArray(), - ArgumentFragment.begin()->Spelling); + std::string ProperArgName = T.getAsString(); ArgumentFragment.begin()->Spelling.swap(ProperArgName); } Fragments.append(std::move(ArgumentFragment)) @@ -570,12 +565,7 @@ DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) { if (StringRef(TypeFragments.begin()->Spelling) .starts_with("type-parameter")) { - std::string ProperArgName = getNameForTemplateArgument( - dyn_cast(Param->getDeclContext()) - ->getDescribedFunctionTemplate() - ->getTemplateParameters() - ->asArray(), - TypeFragments.begin()->Spelling); + std::string ProperArgName = Param->getOriginalType().getAsString(); TypeFragments.begin()->Spelling.swap(ProperArgName); } @@ -668,11 +658,7 @@ DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) { getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After); if (StringRef(ReturnValueFragment.begin()->Spelling) .starts_with("type-parameter")) { - std::string ProperArgName = - getNameForTemplateArgument(Func->getDescribedFunctionTemplate() - ->getTemplateParameters() - ->asArray(), - ReturnValueFragment.begin()->Spelling); + std::string ProperArgName = Func->getReturnType().getAsString(); ReturnValueFragment.begin()->Spelling.swap(ProperArgName); } @@ -961,25 +947,6 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateParameters( return Fragments; } -// Find the name of a template argument from the template's parameters. -std::string DeclarationFragmentsBuilder::getNameForTemplateArgument( - const ArrayRef TemplateParameters, std::string TypeParameter) { - // The arg is a generic parameter from a partial spec, e.g. - // T in template Foo. - // - // Those names appear as "type-parameter--", so we must find its - // name from the template's parameter list. - for (unsigned i = 0; i < TemplateParameters.size(); ++i) { - const auto *Parameter = - dyn_cast(TemplateParameters[i]); - if (TypeParameter.compare("type-parameter-" + - std::to_string(Parameter->getDepth()) + "-" + - std::to_string(Parameter->getIndex())) == 0) - return std::string(TemplateParameters[i]->getName()); - } - llvm_unreachable("Could not find the name of a template argument."); -} - // Get fragments for template arguments, e.g. int in template // Foo; // @@ -989,7 +956,7 @@ std::string DeclarationFragmentsBuilder::getNameForTemplateArgument( DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTemplateArguments( const ArrayRef TemplateArguments, ASTContext &Context, - const std::optional> TemplateParameters) { + const std::optional> TemplateArgumentLocs) { DeclarationFragments Fragments; for (unsigned i = 0, end = TemplateArguments.size(); i != end; ++i) { if (i) @@ -1003,8 +970,10 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateArguments( if (StringRef(ArgumentFragment.begin()->Spelling) .starts_with("type-parameter")) { - std::string ProperArgName = getNameForTemplateArgument( - TemplateParameters.value(), ArgumentFragment.begin()->Spelling); + std::string ProperArgName = TemplateArgumentLocs.value()[i] + .getTypeSourceInfo() + ->getType() + .getAsString(); ArgumentFragment.begin()->Spelling.swap(ProperArgName); } Fragments.append(std::move(ArgumentFragment)); @@ -1089,7 +1058,7 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization( .append("<", DeclarationFragments::FragmentKind::Text) .append(getFragmentsForTemplateArguments( Decl->getTemplateArgs().asArray(), Decl->getASTContext(), - Decl->getTemplateParameters()->asArray())) + Decl->getTemplateArgsAsWritten()->arguments())) .append(">", DeclarationFragments::FragmentKind::Text) .append(";", DeclarationFragments::FragmentKind::Text); } @@ -1130,7 +1099,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization( .append("<", DeclarationFragments::FragmentKind::Text) .append(getFragmentsForTemplateArguments( Decl->getTemplateArgs().asArray(), Decl->getASTContext(), - Decl->getTemplateParameters()->asArray())) + Decl->getTemplateArgsAsWritten()->arguments())) .append(">", DeclarationFragments::FragmentKind::Text) .append(";", DeclarationFragments::FragmentKind::Text); } diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 46ed5baaeacead..e41cf2902a6818 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -955,6 +955,8 @@ template <> struct MappingTraits { Style.BreakBeforeTernaryOperators); IO.mapOptional("BreakConstructorInitializers", Style.BreakConstructorInitializers); + IO.mapOptional("BreakFunctionDefinitionParameters", + Style.BreakFunctionDefinitionParameters); IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList); IO.mapOptional("BreakStringLiterals", Style.BreakStringLiterals); IO.mapOptional("BreakTemplateDeclarations", @@ -1465,6 +1467,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline; LLVMStyle.BreakBeforeTernaryOperators = true; LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; + LLVMStyle.BreakFunctionDefinitionParameters = false; LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; LLVMStyle.BreakStringLiterals = true; LLVMStyle.BreakTemplateDeclarations = FormatStyle::BTDS_MultiLine; diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 2ddcd5259446f6..48b6a9092a8c09 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -574,6 +574,9 @@ struct FormatToken { /// Is optional and can be removed. bool Optional = false; + /// Might be function declaration open/closing paren. + bool MightBeFunctionDeclParen = false; + /// Number of optional braces to be inserted after this token: /// -1: a single left brace /// 0: no braces diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index b9144cf55452e2..a405a348403bdf 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1550,6 +1550,7 @@ class AnnotatingParser { (!Previous->isAttribute() && !Previous->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation))) { Line.MightBeFunctionDecl = true; + Tok->MightBeFunctionDeclParen = true; } } break; @@ -5392,6 +5393,12 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line, if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0) return true; + if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl && + Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen && + Left.ParameterCount > 0) { + return true; + } + if (Style.isCSharp()) { if (Left.is(TT_FatArrow) && Right.is(tok::l_brace) && Style.BraceWrapping.AfterFunction) { diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 79ebb0ae0ee98f..6e3baf83864415 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1206,16 +1206,6 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, // Note the name of the module we're building. Invocation->getLangOpts().CurrentModule = std::string(ModuleName); - // Make sure that the failed-module structure has been allocated in - // the importing instance, and propagate the pointer to the newly-created - // instance. - PreprocessorOptions &ImportingPPOpts - = ImportingInstance.getInvocation().getPreprocessorOpts(); - if (!ImportingPPOpts.FailedModules) - ImportingPPOpts.FailedModules = - std::make_shared(); - PPOpts.FailedModules = ImportingPPOpts.FailedModules; - // If there is a module map file, build the module using the module map. // Set up the inputs/outputs so that we build the module from its umbrella // header. @@ -1269,6 +1259,13 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, SourceMgr.pushModuleBuildStack(ModuleName, FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); + // Make sure that the failed-module structure has been allocated in + // the importing instance, and propagate the pointer to the newly-created + // instance. + if (!ImportingInstance.hasFailedModulesSet()) + ImportingInstance.createFailedModulesSet(); + Instance.setFailedModulesSet(ImportingInstance.getFailedModulesSetPtr()); + // If we're collecting module dependencies, we need to share a collector // between all of the module CompilerInstances. Other than that, we don't // want to produce any dependency output from the module build. @@ -1992,10 +1989,8 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( return nullptr; } - // Check whether we have already attempted to build this module (but - // failed). - if (getPreprocessorOpts().FailedModules && - getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { + // Check whether we have already attempted to build this module (but failed). + if (FailedModules && FailedModules->hasAlreadyFailed(ModuleName)) { getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); return nullptr; @@ -2006,8 +2001,8 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( ModuleFilename)) { assert(getDiagnostics().hasErrorOccurred() && "undiagnosed error in compileModuleAndReadAST"); - if (getPreprocessorOpts().FailedModules) - getPreprocessorOpts().FailedModules->addFailed(ModuleName); + if (FailedModules) + FailedModules->addFailed(ModuleName); return nullptr; } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index f1bd3cd66e97dc..c5bfb8ef1b5607 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3516,7 +3516,8 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, GenerateArg(Consumer, OPT_fblocks); if (Opts.ConvergentFunctions && - !(Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Opts.SYCLIsDevice)) + !(Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Opts.SYCLIsDevice || + Opts.HLSL)) GenerateArg(Consumer, OPT_fconvergent_functions); if (Opts.NoBuiltin && !Opts.Freestanding) @@ -3914,7 +3915,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.ConvergentFunctions = Args.hasArg(OPT_fconvergent_functions) || Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || - Opts.SYCLIsDevice; + Opts.SYCLIsDevice || Opts.HLSL; Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding; if (!Opts.NoBuiltin) diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 3fd1cdd3b47942..0bc26b694cfc8d 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -69,7 +69,10 @@ void InitOnlyAction::ExecuteAction() { // Basically PreprocessOnlyAction::ExecuteAction. void ReadPCHAndPreprocessAction::ExecuteAction() { - Preprocessor &PP = getCompilerInstance().getPreprocessor(); + CompilerInstance &CI = getCompilerInstance(); + AdjustCI(CI); + + Preprocessor &PP = CI.getPreprocessor(); // Ignore unknown pragmas. PP.IgnorePragmas(); @@ -1188,6 +1191,8 @@ void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() { void GetDependenciesByModuleNameAction::ExecuteAction() { CompilerInstance &CI = getCompilerInstance(); + AdjustCI(CI); + Preprocessor &PP = CI.getPreprocessor(); SourceManager &SM = PP.getSourceManager(); FileID MainFileID = SM.getMainFileID(); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index a34e72402c0e64..9fb6204f90c9a8 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -1248,25 +1248,25 @@ float4 rsqrt(float4); /// rounded to the nearest even value. _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round) +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven) half round(half); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round) +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven) half2 round(half2); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round) +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven) half3 round(half3); _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round) +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven) half4 round(half4); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round) +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven) float round(float); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round) +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven) float2 round(float2); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round) +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven) float3 round(float3); -_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round) +_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven) float4 round(float4); //===----------------------------------------------------------------------===// diff --git a/clang/lib/InstallAPI/CMakeLists.txt b/clang/lib/InstallAPI/CMakeLists.txt index 894db699578f20..e0bc8d969ecb3a 100644 --- a/clang/lib/InstallAPI/CMakeLists.txt +++ b/clang/lib/InstallAPI/CMakeLists.txt @@ -1,6 +1,7 @@ set(LLVM_LINK_COMPONENTS Support TextAPI + TextAPIBinaryReader Demangle Core ) diff --git a/clang/lib/InstallAPI/DylibVerifier.cpp b/clang/lib/InstallAPI/DylibVerifier.cpp index ba25e4183a9b89..c0eda1d81b9b98 100644 --- a/clang/lib/InstallAPI/DylibVerifier.cpp +++ b/clang/lib/InstallAPI/DylibVerifier.cpp @@ -10,6 +10,7 @@ #include "clang/InstallAPI/FrontendRecords.h" #include "clang/InstallAPI/InstallAPIDiagnostic.h" #include "llvm/Demangle/Demangle.h" +#include "llvm/TextAPI/DylibReader.h" using namespace llvm::MachO; @@ -35,6 +36,14 @@ struct DylibVerifier::SymbolContext { bool Inlined = false; }; +struct DylibVerifier::DWARFContext { + // Track whether DSYM parsing has already been attempted to avoid re-parsing. + bool ParsedDSYM{false}; + + // Lookup table for source locations by symbol name. + DylibReader::SymbolToSourceLocMap SourceLocs{}; +}; + static bool isCppMangled(StringRef Name) { // InstallAPI currently only supports itanium manglings. return (Name.starts_with("_Z") || Name.starts_with("__Z") || @@ -511,14 +520,16 @@ DylibVerifier::Result DylibVerifier::verify(GlobalRecord *R, return verifyImpl(R, SymCtx); } -void DylibVerifier::VerifierContext::emitDiag( - llvm::function_ref Report) { +void DylibVerifier::VerifierContext::emitDiag(llvm::function_ref Report, + RecordLoc *Loc) { if (!DiscoveredFirstError) { Diag->Report(diag::warn_target) << (PrintArch ? getArchitectureName(Target.Arch) : getTargetTripleName(Target)); DiscoveredFirstError = true; } + if (Loc && Loc->isValid()) + llvm::errs() << Loc->File << ":" << Loc->Line << ":" << 0 << ": "; Report(); } @@ -561,26 +572,36 @@ void DylibVerifier::visitSymbolInDylib(const Record &R, SymbolContext &SymCtx) { return; } - // All checks at this point classify as some kind of violation that should be - // reported. + const bool IsLinkerSymbol = SymbolName.starts_with("$ld$"); + + // All checks at this point classify as some kind of violation. + // The different verification modes dictate whether they are reported to the + // user. + if (IsLinkerSymbol || (Mode > VerificationMode::ErrorsOnly)) + accumulateSrcLocForDylibSymbols(); + RecordLoc Loc = DWARFCtx->SourceLocs.lookup(SymCtx.SymbolName); // Regardless of verification mode, error out on mismatched special linker // symbols. - if (SymbolName.starts_with("$ld$")) { - Ctx.emitDiag([&]() { - Ctx.Diag->Report(diag::err_header_symbol_missing) - << getAnnotatedName(&R, SymCtx, /*ValidSourceLoc=*/false); - }); + if (IsLinkerSymbol) { + Ctx.emitDiag( + [&]() { + Ctx.Diag->Report(diag::err_header_symbol_missing) + << getAnnotatedName(&R, SymCtx, Loc.isValid()); + }, + &Loc); updateState(Result::Invalid); return; } // Missing declarations for exported symbols are hard errors on Pedantic mode. if (Mode == VerificationMode::Pedantic) { - Ctx.emitDiag([&]() { - Ctx.Diag->Report(diag::err_header_symbol_missing) - << getAnnotatedName(&R, SymCtx, /*ValidSourceLoc=*/false); - }); + Ctx.emitDiag( + [&]() { + Ctx.Diag->Report(diag::err_header_symbol_missing) + << getAnnotatedName(&R, SymCtx, Loc.isValid()); + }, + &Loc); updateState(Result::Invalid); return; } @@ -588,10 +609,12 @@ void DylibVerifier::visitSymbolInDylib(const Record &R, SymbolContext &SymCtx) { // Missing declarations for exported symbols are warnings on ErrorsAndWarnings // mode. if (Mode == VerificationMode::ErrorsAndWarnings) { - Ctx.emitDiag([&]() { - Ctx.Diag->Report(diag::warn_header_symbol_missing) - << getAnnotatedName(&R, SymCtx, /*ValidSourceLoc=*/false); - }); + Ctx.emitDiag( + [&]() { + Ctx.Diag->Report(diag::warn_header_symbol_missing) + << getAnnotatedName(&R, SymCtx, Loc.isValid()); + }, + &Loc); updateState(Result::Ignore); return; } @@ -622,6 +645,18 @@ void DylibVerifier::visitObjCIVar(const ObjCIVarRecord &R, visitSymbolInDylib(R, SymCtx); } +void DylibVerifier::accumulateSrcLocForDylibSymbols() { + if (DSYMPath.empty()) + return; + + assert(DWARFCtx != nullptr && "Expected an initialized DWARFContext"); + if (DWARFCtx->ParsedDSYM) + return; + DWARFCtx->ParsedDSYM = true; + DWARFCtx->SourceLocs = + DylibReader::accumulateSourceLocFromDSYM(DSYMPath, Ctx.Target); +} + void DylibVerifier::visitObjCInterface(const ObjCInterfaceRecord &R) { if (R.isVerified()) return; @@ -655,6 +690,8 @@ DylibVerifier::Result DylibVerifier::verifyRemainingSymbols() { return Result::NoVerify; assert(!Dylib.empty() && "No binary to verify against"); + DWARFContext DWARFInfo; + DWARFCtx = &DWARFInfo; Ctx.DiscoveredFirstError = false; Ctx.PrintArch = true; for (std::shared_ptr Slice : Dylib) { diff --git a/clang/lib/InstallAPI/Visitor.cpp b/clang/lib/InstallAPI/Visitor.cpp index 6476c5107cb5cc..cf3aaa4c6ec931 100644 --- a/clang/lib/InstallAPI/Visitor.cpp +++ b/clang/lib/InstallAPI/Visitor.cpp @@ -205,10 +205,10 @@ bool InstallAPIVisitor::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { const ObjCInterfaceDecl *InterfaceD = D->getClassInterface(); const StringRef InterfaceName = InterfaceD->getName(); - std::pair Category = - Ctx.Slice->addObjCCategory(InterfaceName, CategoryName, Avail, D, - *Access); - recordObjCInstanceVariables(D->getASTContext(), Category.first, InterfaceName, + ObjCCategoryRecord *CategoryRecord = + Ctx.Slice->addObjCCategory(InterfaceName, CategoryName, Avail, D, *Access) + .first; + recordObjCInstanceVariables(D->getASTContext(), CategoryRecord, InterfaceName, D->ivars()); return true; } diff --git a/clang/lib/Interpreter/Value.cpp b/clang/lib/Interpreter/Value.cpp index 1d6b2da087e9fb..eb2ce9c9fd3302 100644 --- a/clang/lib/Interpreter/Value.cpp +++ b/clang/lib/Interpreter/Value.cpp @@ -1,4 +1,4 @@ -//===--- Interpreter.h - Incremental Compiation and Execution---*- C++ -*-===// +//===------------ Value.cpp - Definition of interpreter value -------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,8 +22,6 @@ #include #include -using namespace clang; - namespace { // This is internal buffer maintained by Value, used to hold temporaries. @@ -61,7 +59,7 @@ class ValueStorage { void Release() { assert(RefCnt > 0 && "Can't release if reference count is already zero"); if (--RefCnt == 0) { - // We hace a non-trivial dtor. + // We have a non-trivial dtor. if (Dtor && IsAlive()) { assert(Elements && "We at least should have 1 element in Value"); size_t Stride = AllocSize / Elements; @@ -97,6 +95,8 @@ class ValueStorage { }; } // namespace +namespace clang { + static Value::Kind ConvertQualTypeToKind(const ASTContext &Ctx, QualType QT) { if (Ctx.hasSameType(QT, Ctx.VoidTy)) return Value::K_Void; @@ -265,3 +265,5 @@ void Value::print(llvm::raw_ostream &Out) const { assert(OpaqueType != nullptr && "Can't print default Value"); Out << "Not implement yet.\n"; } + +} // namespace clang diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index 3b1b6df1dbae4e..a0cc2b516574c1 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -93,16 +93,10 @@ bool Preprocessor::EnterSourceFile(FileID FID, ConstSearchDirIterator CurDir, } Lexer *TheLexer = new Lexer(FID, *InputFile, *this, IsFirstIncludeOfFile); - if (getPreprocessorOpts().DependencyDirectivesForFile && - FID != PredefinesFileID) { - if (OptionalFileEntryRef File = SourceMgr.getFileEntryRefForID(FID)) { - if (std::optional> - DepDirectives = - getPreprocessorOpts().DependencyDirectivesForFile(*File)) { + if (DependencyDirectivesForFile && FID != PredefinesFileID) + if (OptionalFileEntryRef File = SourceMgr.getFileEntryRefForID(FID)) + if (auto DepDirectives = DependencyDirectivesForFile(*File)) TheLexer->DepDirectives = *DepDirectives; - } - } - } EnterSourceFileWithLexer(TheLexer, CurDir); return false; diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index 50e3c39f60919b..07dd2ba0106a4e 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -14,6 +14,7 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" #include "clang/Parse/RAIIObjectsForParser.h" +#include "clang/Sema/SemaOpenACC.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" @@ -777,7 +778,7 @@ bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) { SourceLocation ClauseLoc = ConsumeToken(); bool Result = ParseOpenACCClauseParams(DirKind, Kind); - getActions().ActOnOpenACCClause(Kind, ClauseLoc); + getActions().OpenACC().ActOnClause(Kind, ClauseLoc); return Result; } @@ -1151,7 +1152,7 @@ Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() { SourceLocation StartLoc = getCurToken().getLocation(); OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this); - getActions().ActOnOpenACCConstruct(DirKind, StartLoc); + getActions().OpenACC().ActOnConstruct(DirKind, StartLoc); // Once we've parsed the construct/directive name, some have additional // specifiers that need to be taken care of. Atomic has an 'atomic-clause' @@ -1223,12 +1224,12 @@ Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() { OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective(); - if (getActions().ActOnStartOpenACCDeclDirective(DirInfo.DirKind, - DirInfo.StartLoc)) + if (getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind, + DirInfo.StartLoc)) return nullptr; // TODO OpenACC: Do whatever decl parsing is required here. - return DeclGroupPtrTy::make(getActions().ActOnEndOpenACCDeclDirective()); + return DeclGroupPtrTy::make(getActions().OpenACC().ActOnEndDeclDirective()); } // Parse OpenACC Directive on a Statement. @@ -1239,8 +1240,8 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() { ConsumeAnnotationToken(); OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective(); - if (getActions().ActOnStartOpenACCStmtDirective(DirInfo.DirKind, - DirInfo.StartLoc)) + if (getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind, + DirInfo.StartLoc)) return StmtError(); StmtResult AssocStmt; @@ -1249,10 +1250,10 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() { ParsingOpenACCDirectiveRAII DirScope(*this, /*Value=*/false); ParseScope ACCScope(this, getOpenACCScopeFlags(DirInfo.DirKind)); - AssocStmt = getActions().ActOnOpenACCAssociatedStmt(DirInfo.DirKind, - ParseStatement()); + AssocStmt = getActions().OpenACC().ActOnAssociatedStmt(DirInfo.DirKind, + ParseStatement()); } - return getActions().ActOnEndOpenACCStmtDirective( + return getActions().OpenACC().ActOnEndStmtDirective( DirInfo.DirKind, DirInfo.StartLoc, DirInfo.EndLoc, AssocStmt); } diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index 6722878883be8e..ce6211c23218bb 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -16,6 +16,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenACC.h" #include "clang/AST/StmtOpenMP.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/SemaInternal.h" diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 72393bea620526..b7e4fc0ac9b5b2 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -43,6 +43,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaConsumer.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaOpenACC.h" #include "clang/Sema/TemplateDeduction.h" #include "clang/Sema/TemplateInstCallback.h" #include "clang/Sema/TypoCorrection.h" @@ -196,7 +197,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, ThreadSafetyDeclCache(nullptr), LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), CurContext(nullptr), ExternalSource(nullptr), CurScope(nullptr), - Ident_super(nullptr), + Ident_super(nullptr), OpenACCPtr(std::make_unique(*this)), MSPointerToMemberRepresentationMethod( LangOpts.getMSPointerToMemberRepresentationMethod()), MSStructPragmaOn(false), VtorDispStack(LangOpts.getVtorDispMode()), @@ -653,6 +654,7 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty, case CK_FunctionToPointerDecay: case CK_ToVoid: case CK_NonAtomicToAtomic: + case CK_HLSLArrayRValue: break; } } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a1ce867248a49b..3dcd18b3afc8b4 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5651,6 +5651,7 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case Builtin::BI__builtin_elementwise_log2: case Builtin::BI__builtin_elementwise_log10: case Builtin::BI__builtin_elementwise_pow: + case Builtin::BI__builtin_elementwise_roundeven: case Builtin::BI__builtin_elementwise_sin: case Builtin::BI__builtin_elementwise_sqrt: case Builtin::BI__builtin_elementwise_trunc: { @@ -12454,6 +12455,19 @@ isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE) { S.Context.getFloatingTypeOrder(From, To) < 0; } +static analyze_format_string::ArgType::MatchKind +handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, + DiagnosticsEngine &Diags, SourceLocation Loc) { + if (Match == analyze_format_string::ArgType::NoMatchSignedness) { + Match = + Diags.isIgnored( + diag::warn_format_conversion_argument_type_mismatch_signedness, Loc) + ? analyze_format_string::ArgType::Match + : analyze_format_string::ArgType::NoMatch; + } + return Match; +} + bool CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, const char *StartSpecifier, @@ -12497,6 +12511,9 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, ArgType::MatchKind ImplicitMatch = ArgType::NoMatch; ArgType::MatchKind Match = AT.matchesType(S.Context, ExprTy); + ArgType::MatchKind OrigMatch = Match; + + Match = handleFormatSignedness(Match, S.getDiagnostics(), E->getExprLoc()); if (Match == ArgType::Match) return true; @@ -12520,6 +12537,14 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, ICE->getType() == S.Context.UnsignedIntTy) { // All further checking is done on the subexpression ImplicitMatch = AT.matchesType(S.Context, ExprTy); + if (OrigMatch == ArgType::NoMatchSignedness && + ImplicitMatch != ArgType::NoMatchSignedness) + // If the original match was a signedness match this match on the + // implicit cast type also need to be signedness match otherwise we + // might introduce new unexpected warnings from -Wformat-signedness. + return true; + ImplicitMatch = handleFormatSignedness( + ImplicitMatch, S.getDiagnostics(), E->getExprLoc()); if (ImplicitMatch == ArgType::Match) return true; } @@ -12641,6 +12666,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, case ArgType::Match: case ArgType::MatchPromotion: case ArgType::NoMatchPromotionTypeConfusion: + case ArgType::NoMatchSignedness: llvm_unreachable("expected non-matching"); case ArgType::NoMatchPedantic: Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic; @@ -12676,8 +12702,10 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, CastFix << (S.LangOpts.CPlusPlus ? ">" : ")"); SmallVector Hints; - if (AT.matchesType(S.Context, IntendedTy) != ArgType::Match || - ShouldNotPrintDirectly) + ArgType::MatchKind IntendedMatch = AT.matchesType(S.Context, IntendedTy); + IntendedMatch = handleFormatSignedness(IntendedMatch, S.getDiagnostics(), + E->getExprLoc()); + if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly) Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str())); if (const CStyleCastExpr *CCast = dyn_cast(E)) { @@ -12746,6 +12774,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, case ArgType::Match: case ArgType::MatchPromotion: case ArgType::NoMatchPromotionTypeConfusion: + case ArgType::NoMatchSignedness: llvm_unreachable("expected non-matching"); case ArgType::NoMatchPedantic: Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic; @@ -12957,6 +12986,7 @@ bool CheckScanfHandler::HandleScanfSpecifier( analyze_format_string::ArgType::MatchKind Match = AT.matchesType(S.Context, Ex->getType()); + Match = handleFormatSignedness(Match, S.getDiagnostics(), Ex->getExprLoc()); bool Pedantic = Match == analyze_format_string::ArgType::NoMatchPedantic; if (Match == analyze_format_string::ArgType::Match) return true; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 19a52a2d703796..5c1152896559b5 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -9915,7 +9915,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // FIXME: We need a better way to separate C++ standard and clang modules. bool ImplicitInlineCXX20 = !getLangOpts().CPlusPlusModules || !NewFD->getOwningModule() || - NewFD->getOwningModule()->isGlobalModule() || + NewFD->isFromExplicitGlobalModule() || NewFD->getOwningModule()->isHeaderLikeModule(); bool isInline = D.getDeclSpec().isInlineSpecified(); bool isVirtual = D.getDeclSpec().isVirtualSpecified(); @@ -10124,23 +10124,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual); } - if (getLangOpts().CPlusPlus14 && - (NewFD->isDependentContext() || - (isFriend && CurContext->isDependentContext())) && - NewFD->getReturnType()->isUndeducedType()) { - // If the function template is referenced directly (for instance, as a - // member of the current instantiation), pretend it has a dependent type. - // This is not really justified by the standard, but is the only sane - // thing to do. - // FIXME: For a friend function, we have not marked the function as being - // a friend yet, so 'isDependentContext' on the FD doesn't work. - const FunctionProtoType *FPT = - NewFD->getType()->castAs(); - QualType Result = SubstAutoTypeDependent(FPT->getReturnType()); - NewFD->setType(Context.getFunctionType(Result, FPT->getParamTypes(), - FPT->getExtProtoInfo())); - } - // C++ [dcl.fct.spec]p3: // The inline specifier shall not appear on a block scope function // declaration. @@ -12112,6 +12095,35 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, CheckConstPureAttributesUsage(*this, NewFD); + // C++ [dcl.spec.auto.general]p12: + // Return type deduction for a templated function with a placeholder in its + // declared type occurs when the definition is instantiated even if the + // function body contains a return statement with a non-type-dependent + // operand. + // + // C++ [temp.dep.expr]p3: + // An id-expression is type-dependent if it is a template-id that is not a + // concept-id and is dependent; or if its terminal name is: + // - [...] + // - associated by name lookup with one or more declarations of member + // functions of a class that is the current instantiation declared with a + // return type that contains a placeholder type, + // - [...] + // + // If this is a templated function with a placeholder in its return type, + // make the placeholder type dependent since it won't be deduced until the + // definition is instantiated. We do this here because it needs to happen + // for implicitly instantiated member functions/member function templates. + if (getLangOpts().CPlusPlus14 && + (NewFD->isDependentContext() && + NewFD->getReturnType()->isUndeducedType())) { + const FunctionProtoType *FPT = + NewFD->getType()->castAs(); + QualType NewReturnType = SubstAutoTypeDependent(FPT->getReturnType()); + NewFD->setType(Context.getFunctionType(NewReturnType, FPT->getParamTypes(), + FPT->getExtProtoInfo())); + } + // C++11 [dcl.constexpr]p8: // A constexpr specifier for a non-static member function that is not // a constructor declares that member function to be const. @@ -18170,7 +18182,9 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, cast_or_null(PrevDecl)); } - if (OOK != OOK_Outside && TUK == TUK_Definition && !getLangOpts().CPlusPlus) + // Only C23 and later allow defining new types in 'offsetof()'. + if (OOK != OOK_Outside && TUK == TUK_Definition && !getLangOpts().CPlusPlus && + !getLangOpts().C23) Diag(New->getLocation(), diag::ext_type_defined_in_offsetof) << (OOK == OOK_Macro) << New->getSourceRange(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 091fc3e4836b63..80b4257d9d83ed 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -658,8 +658,9 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { QualType T = E->getType(); assert(!T.isNull() && "r-value conversion on typeless expression?"); - // lvalue-to-rvalue conversion cannot be applied to function or array types. - if (T->isFunctionType() || T->isArrayType()) + // lvalue-to-rvalue conversion cannot be applied to types that decay to + // pointers (i.e. function or array types). + if (T->canDecayToPointerType()) return E; // We don't want to throw lvalue-to-rvalue casts on top of @@ -4686,6 +4687,9 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T, case Type::Decayed: T = cast(Ty)->getPointeeType(); break; + case Type::ArrayParameter: + T = cast(Ty)->getElementType(); + break; case Type::Pointer: T = cast(Ty)->getPointeeType(); break; @@ -12908,6 +12912,8 @@ static ImplicitConversionKind castKindToImplicitConversionKind(CastKind CK) { case CK_IntegralComplexToReal: case CK_IntegralRealToComplex: return ICK_Complex_Real; + case CK_HLSLArrayRValue: + return ICK_HLSL_Array_RValue; } } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 51c8e04bee8c31..76bb78aa8b5458 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4416,6 +4416,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, .get(); break; + case ICK_HLSL_Array_RValue: + FromType = Context.getArrayParameterType(FromType); + From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue, + /*BasePath=*/nullptr, CCK) + .get(); + break; + case ICK_Function_To_Pointer: FromType = Context.getPointerType(FromType); From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay, @@ -4793,6 +4800,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, case ICK_Num_Conversion_Kinds: case ICK_C_Only_Conversion: case ICK_Incompatible_Pointer_Conversion: + case ICK_HLSL_Array_RValue: llvm_unreachable("Improper second standard conversion"); } diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 3382d56303d628..e2a1951f1062cb 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -6269,7 +6269,10 @@ void InitializationSequence::InitializeFrom(Sema &S, // initializer is a string literal, see 8.5.2. // - Otherwise, if the destination type is an array, the program is // ill-formed. - if (const ArrayType *DestAT = Context.getAsArrayType(DestType)) { + // - Except in HLSL, where non-decaying array parameters behave like + // non-array types for initialization. + if (DestType->isArrayType() && !DestType->isArrayParameterType()) { + const ArrayType *DestAT = Context.getAsArrayType(DestType); if (Initializer && isa(DestAT)) { SetFailed(FK_VariableLengthArrayHasInitializer); return; diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index d3a9c7abd0e944..38237ee578079d 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3243,6 +3243,10 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { case Type::Pipe: T = cast(T)->getElementType().getTypePtr(); continue; + + // Array parameter types are treated as fundamental types. + case Type::ArrayParameter: + break; } if (Queue.empty()) diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index d3a602d1c382fa..2ac994cac71e19 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -11,14 +11,15 @@ /// //===----------------------------------------------------------------------===// +#include "clang/AST/StmtOpenACC.h" +#include "clang/Sema/SemaOpenACC.h" #include "clang/Basic/DiagnosticSema.h" -#include "clang/Basic/OpenACCKinds.h" #include "clang/Sema/Sema.h" using namespace clang; namespace { -bool diagnoseConstructAppertainment(Sema &S, OpenACCDirectiveKind K, +bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K, SourceLocation StartLoc, bool IsStmt) { switch (K) { default: @@ -30,14 +31,21 @@ bool diagnoseConstructAppertainment(Sema &S, OpenACCDirectiveKind K, case OpenACCDirectiveKind::Serial: case OpenACCDirectiveKind::Kernels: if (!IsStmt) - return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K; + return S.SemaRef.Diag(StartLoc, diag::err_acc_construct_appertainment) + << K; break; } return false; } } // namespace -bool Sema::ActOnOpenACCClause(OpenACCClauseKind ClauseKind, +SemaOpenACC::SemaOpenACC(Sema &S) : SemaRef(S) {} + +ASTContext &SemaOpenACC::getASTContext() const { return SemaRef.Context; } +DiagnosticsEngine &SemaOpenACC::getDiagnostics() const { return SemaRef.Diags; } +const LangOptions &SemaOpenACC::getLangOpts() const { return SemaRef.LangOpts; } + +bool SemaOpenACC::ActOnClause(OpenACCClauseKind ClauseKind, SourceLocation StartLoc) { if (ClauseKind == OpenACCClauseKind::Invalid) return false; @@ -45,9 +53,10 @@ bool Sema::ActOnOpenACCClause(OpenACCClauseKind ClauseKind, // whatever it can do. This function will eventually need to start returning // some sort of Clause AST type, but for now just return true/false based on // success. - return Diag(StartLoc, diag::warn_acc_clause_unimplemented) << ClauseKind; + return SemaRef.Diag(StartLoc, diag::warn_acc_clause_unimplemented) + << ClauseKind; } -void Sema::ActOnOpenACCConstruct(OpenACCDirectiveKind K, +void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc) { switch (K) { case OpenACCDirectiveKind::Invalid: @@ -63,17 +72,17 @@ void Sema::ActOnOpenACCConstruct(OpenACCDirectiveKind K, // here as these constructs do not take any arguments. break; default: - Diag(StartLoc, diag::warn_acc_construct_unimplemented) << K; + SemaRef.Diag(StartLoc, diag::warn_acc_construct_unimplemented) << K; break; } } -bool Sema::ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K, +bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc) { return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true); } -StmtResult Sema::ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K, +StmtResult SemaOpenACC::ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation EndLoc, StmtResult AssocStmt) { @@ -92,7 +101,7 @@ StmtResult Sema::ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K, llvm_unreachable("Unhandled case in directive handling?"); } -StmtResult Sema::ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K, +StmtResult SemaOpenACC::ActOnAssociatedStmt(OpenACCDirectiveKind K, StmtResult AssocStmt) { switch (K) { default: @@ -114,9 +123,9 @@ StmtResult Sema::ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K, llvm_unreachable("Invalid associated statement application"); } -bool Sema::ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K, +bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc) { return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false); } -DeclGroupRef Sema::ActOnEndOpenACCDeclDirective() { return DeclGroupRef{}; } +DeclGroupRef SemaOpenACC::ActOnEndDeclDirective() { return DeclGroupRef{}; } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index de0c2e7399632b..0c913bc700f4a1 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -160,6 +160,7 @@ ImplicitConversionRank clang::GetConversionRank(ImplicitConversionKind Kind) { ICR_C_Conversion_Extension, ICR_Conversion, ICR_Conversion, + ICR_Conversion, }; static_assert(std::size(Rank) == (int)ICK_Num_Conversion_Kinds); return Rank[(int)Kind]; @@ -201,6 +202,7 @@ static const char *GetImplicitConversionName(ImplicitConversionKind Kind) { "Incompatible pointer conversion", "Fixed point conversion", "HLSL vector truncation", + "Non-decaying array conversion", }; static_assert(std::size(Name) == (int)ICK_Num_Conversion_Kinds); return Name[Kind]; @@ -2131,8 +2133,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, // A glvalue (3.10) of a non-function, non-array type T can // be converted to a prvalue. bool argIsLValue = From->isGLValue(); - if (argIsLValue && - !FromType->isFunctionType() && !FromType->isArrayType() && + if (argIsLValue && !FromType->canDecayToPointerType() && S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) { SCS.First = ICK_Lvalue_To_Rvalue; @@ -2147,6 +2148,19 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, // is T (C++ 4.1p1). C++ can't get here with class types; in C, we // just strip the qualifiers because they don't matter. FromType = FromType.getUnqualifiedType(); + } else if (S.getLangOpts().HLSL && FromType->isConstantArrayType() && + ToType->isArrayParameterType()) { + // HLSL constant array parameters do not decay, so if the argument is a + // constant array and the parameter is an ArrayParameterType we have special + // handling here. + FromType = S.Context.getArrayParameterType(FromType); + if (S.Context.getCanonicalType(FromType) != + S.Context.getCanonicalType(ToType)) + return false; + + SCS.First = ICK_HLSL_Array_RValue; + SCS.setAllToTypes(ToType); + return true; } else if (FromType->isArrayType()) { // Array-to-pointer conversion (C++ 4.2) SCS.First = ICK_Array_To_Pointer; @@ -6100,6 +6114,7 @@ static bool CheckConvertedConstantConversions(Sema &S, case ICK_Lvalue_To_Rvalue: case ICK_Array_To_Pointer: case ICK_Function_To_Pointer: + case ICK_HLSL_Array_RValue: llvm_unreachable("found a first conversion kind in Second"); case ICK_Function_Conversion: diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index de728305d55aa9..a2b8cc14ca764f 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1836,7 +1836,27 @@ static TemplateParameterList *GetTemplateParameterList(TemplateDecl *TD) { // Make sure we get the template parameter list from the most // recent declaration, since that is the only one that is guaranteed to // have all the default template argument information. - return cast(TD->getMostRecentDecl())->getTemplateParameters(); + Decl *D = TD->getMostRecentDecl(); + // C++11 N3337 [temp.param]p12: + // A default template argument shall not be specified in a friend class + // template declaration. + // + // Skip past friend *declarations* because they are not supposed to contain + // default template arguments. Moreover, these declarations may introduce + // template parameters living in different template depths than the + // corresponding template parameters in TD, causing unmatched constraint + // substitution. + // + // FIXME: Diagnose such cases within a class template: + // template + // struct S { + // template friend struct C; + // }; + // template struct S; + while (D->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None && + D->getPreviousDecl()) + D = D->getPreviousDecl(); + return cast(D)->getTemplateParameters(); } DeclResult Sema::CheckClassTemplate( @@ -2700,6 +2720,12 @@ SmallVector TemplateParamsReferencedInTemplateArgumentList( return true; } + bool TraverseTemplateName(TemplateName Template) { + if (auto *TD = Template.getAsTemplateDecl()) + MarkAppeared(TD); + return RecursiveASTVisitor::TraverseTemplateName(Template); + } + void MarkAppeared(NamedDecl *ND) { if (TemplateParams.contains(ND)) ReferencedTemplateParams.insert(ND); @@ -6879,6 +6905,11 @@ bool UnnamedLocalNoLinkageFinder::VisitBitIntType(const BitIntType *T) { return false; } +bool UnnamedLocalNoLinkageFinder::VisitArrayParameterType( + const ArrayParameterType *T) { + return VisitConstantArrayType(T); +} + bool UnnamedLocalNoLinkageFinder::VisitDependentBitIntType( const DependentBitIntType *T) { return false; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 9a55881f644254..716660244537b8 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2277,6 +2277,7 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( case Type::DependentTemplateSpecialization: case Type::PackExpansion: case Type::Pipe: + case Type::ArrayParameter: // No template argument deduction for these types return TemplateDeductionResult::Success; @@ -6355,11 +6356,11 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, case Type::ConstantArray: case Type::IncompleteArray: + case Type::ArrayParameter: MarkUsedTemplateParameters(Ctx, cast(T)->getElementType(), OnlyDeduced, Depth, Used); break; - case Type::Vector: case Type::ExtVector: MarkUsedTemplateParameters(Ctx, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 2ddc9c0cf5fb5e..8762744396f4dd 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6515,6 +6515,9 @@ namespace { void VisitDecayedTypeLoc(DecayedTypeLoc TL) { llvm_unreachable("decayed type locs not expected here!"); } + void VisitArrayParameterTypeLoc(ArrayParameterTypeLoc TL) { + llvm_unreachable("array parameter type locs not expected here!"); + } void VisitAttributedTypeLoc(AttributedTypeLoc TL) { fillAttributedTypeLoc(TL, State); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 80a10647ca5d33..a2568ad0f82cc2 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -39,6 +39,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaDiagnostic.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaOpenACC.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/ErrorHandling.h" #include @@ -4000,16 +4001,16 @@ class TreeTransform { SourceLocation BeginLoc, SourceLocation EndLoc, StmtResult StrBlock) { - getSema().ActOnOpenACCConstruct(K, BeginLoc); + getSema().OpenACC().ActOnConstruct(K, BeginLoc); // TODO OpenACC: Include clauses. - if (getSema().ActOnStartOpenACCStmtDirective(K, BeginLoc)) + if (getSema().OpenACC().ActOnStartStmtDirective(K, BeginLoc)) return StmtError(); - StrBlock = getSema().ActOnOpenACCAssociatedStmt(K, StrBlock); + StrBlock = getSema().OpenACC().ActOnAssociatedStmt(K, StrBlock); - return getSema().ActOnEndOpenACCStmtDirective(K, BeginLoc, EndLoc, - StrBlock); + return getSema().OpenACC().ActOnEndStmtDirective(K, BeginLoc, EndLoc, + StrBlock); } private: @@ -5243,6 +5244,23 @@ QualType TreeTransform::TransformDecayedType(TypeLocBuilder &TLB, return Result; } +template +QualType +TreeTransform::TransformArrayParameterType(TypeLocBuilder &TLB, + ArrayParameterTypeLoc TL) { + QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc()); + if (OriginalType.isNull()) + return QualType(); + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || + OriginalType != TL.getElementLoc().getType()) + Result = SemaRef.Context.getArrayParameterType(OriginalType); + TLB.push(Result); + // Nothing to set for ArrayParameterTypeLoc. + return Result; +} + template QualType TreeTransform::TransformPointerType(TypeLocBuilder &TLB, PointerTypeLoc TL) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 28e8d27fef08c6..004859ed22bf16 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6810,6 +6810,10 @@ void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { // nothing to do } +void TypeLocReader::VisitArrayParameterTypeLoc(ArrayParameterTypeLoc TL) { + // nothing to do +} + void TypeLocReader::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { TL.setExpansionLoc(readSourceLocation()); } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 674ed47581dfd3..bbeb6db011646f 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1047,30 +1047,22 @@ void ASTStmtReader::VisitMemberExpr(MemberExpr *E) { E->MemberDNLoc = Record.readDeclarationNameLoc(E->MemberDecl->getDeclName()); E->MemberLoc = Record.readSourceLocation(); E->MemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit(); - E->MemberExprBits.HasQualifierOrFoundDecl = HasQualifier || HasFoundDecl; + E->MemberExprBits.HasQualifier = HasQualifier; + E->MemberExprBits.HasFoundDecl = HasFoundDecl; E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateInfo; E->MemberExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit(); E->MemberExprBits.NonOdrUseReason = CurrentUnpackingBits->getNextBits(/*Width=*/2); E->MemberExprBits.OperatorLoc = Record.readSourceLocation(); - if (HasQualifier || HasFoundDecl) { - DeclAccessPair FoundDecl; - if (HasFoundDecl) { - auto *FoundD = Record.readDeclAs(); - auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2); - FoundDecl = DeclAccessPair::make(FoundD, AS); - } else { - FoundDecl = DeclAccessPair::make(E->MemberDecl, - E->MemberDecl->getAccess()); - } - E->getTrailingObjects()->FoundDecl = FoundDecl; + if (HasQualifier) + new (E->getTrailingObjects()) + NestedNameSpecifierLoc(Record.readNestedNameSpecifierLoc()); - NestedNameSpecifierLoc QualifierLoc; - if (HasQualifier) - QualifierLoc = Record.readNestedNameSpecifierLoc(); - E->getTrailingObjects()->QualifierLoc = - QualifierLoc; + if (HasFoundDecl) { + auto *FoundD = Record.readDeclAs(); + auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2); + *E->getTrailingObjects() = DeclAccessPair::make(FoundD, AS); } if (HasTemplateInfo) diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 2cc7f21bf60c49..a2668e61c51d12 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -318,6 +318,10 @@ void TypeLocWriter::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { // nothing to do } +void TypeLocWriter::VisitArrayParameterTypeLoc(ArrayParameterTypeLoc TL) { + // nothing to do +} + void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { addSourceLocation(TL.getCaretLoc()); } @@ -3195,6 +3199,10 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, if (DC->decls_empty()) return 0; + // In reduced BMI, we don't care the declarations in functions. + if (GeneratingReducedBMI && DC->isFunctionOrMethod()) + return 0; + uint64_t Offset = Stream.GetCurrentBitNo(); SmallVector KindDeclPairs; for (const auto *D : DC->decls()) { @@ -4955,38 +4963,12 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, Stream.EmitRecord(METADATA_OLD_FORMAT, Record); } - // Create a lexical update block containing all of the declarations in the - // translation unit that do not come from other AST files. const TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); - SmallVector NewGlobalKindDeclPairs; - for (const auto *D : TU->noload_decls()) { - if (!D->isFromASTFile()) { - NewGlobalKindDeclPairs.push_back(D->getKind()); - NewGlobalKindDeclPairs.push_back(GetDeclRef(D)); - } - } - - auto Abv = std::make_shared(); - Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL)); - Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); - unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv)); - { - RecordData::value_type Record[] = {TU_UPDATE_LEXICAL}; - Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, - bytes(NewGlobalKindDeclPairs)); - } - - // And a visible updates block for the translation unit. - Abv = std::make_shared(); - Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); - Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); - Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); - UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv)); - WriteDeclContextVisibleUpdate(TU); - // If we have any extern "C" names, write out a visible update for them. - if (Context.ExternCContext) - WriteDeclContextVisibleUpdate(Context.ExternCContext); + // Force all top level declarations to be emitted. + for (const auto *D : TU->noload_decls()) + if (!D->isFromASTFile()) + GetDeclRef(D); // If the translation unit has an anonymous namespace, and we don't already // have an update block for it, write it as an update block. @@ -5127,6 +5109,14 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, for (auto *D : SemaRef.DeclsToCheckForDeferredDiags) DeclsToCheckForDeferredDiags.push_back(GetDeclRef(D)); + { + auto Abv = std::make_shared(); + Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); + UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv)); + } + RecordData DeclUpdatesOffsetsRecord; // Keep writing types, declarations, and declaration update records @@ -5154,6 +5144,35 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, WriteTypeDeclOffsets(); if (!DeclUpdatesOffsetsRecord.empty()) Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord); + + // Create a lexical update block containing all of the declarations in the + // translation unit that do not come from other AST files. + { + SmallVector NewGlobalKindDeclPairs; + for (const auto *D : TU->noload_decls()) { + if (!D->isFromASTFile()) { + NewGlobalKindDeclPairs.push_back(D->getKind()); + NewGlobalKindDeclPairs.push_back(GetDeclRef(D)); + } + } + + auto Abv = std::make_shared(); + Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); + unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + RecordData::value_type Record[] = {TU_UPDATE_LEXICAL}; + Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, + bytes(NewGlobalKindDeclPairs)); + } + + // And a visible updates block for the translation unit. + WriteDeclContextVisibleUpdate(TU); + + // If we have any extern "C" names, write out a visible update for them. + if (Context.ExternCContext) + WriteDeclContextVisibleUpdate(Context.ExternCContext); + WriteFileDeclIDsMap(); WriteSourceManagerBlock(Context.getSourceManager(), PP); WriteComments(); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 7ce48fede383ea..22e190450d3918 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -970,10 +970,7 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { VisitExpr(E); bool HasQualifier = E->hasQualifier(); - bool HasFoundDecl = - E->hasQualifierOrFoundDecl() && - (E->getFoundDecl().getDecl() != E->getMemberDecl() || - E->getFoundDecl().getAccess() != E->getMemberDecl()->getAccess()); + bool HasFoundDecl = E->hasFoundDecl(); bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo(); unsigned NumTemplateArgs = E->getNumTemplateArgs(); @@ -995,15 +992,15 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2); Record.AddSourceLocation(E->getOperatorLoc()); + if (HasQualifier) + Record.AddNestedNameSpecifierLoc(E->getQualifierLoc()); + if (HasFoundDecl) { DeclAccessPair FoundDecl = E->getFoundDecl(); Record.AddDeclRef(FoundDecl.getDecl()); CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2); } - if (HasQualifier) - Record.AddNestedNameSpecifierLoc(E->getQualifierLoc()); - if (HasTemplateInfo) AddTemplateKWAndArgsInfo(*E->getTrailingObjects(), E->getTrailingObjects()); diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index 902c42a2799be4..069e3a633c1214 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -1264,15 +1264,10 @@ void StreamChecker::evalFseek(const FnDescription *Desc, const CallEvent &Call, if (!E.Init(Desc, Call, C, State)) return; - const llvm::APSInt *PosV = - C.getSValBuilder().getKnownValue(State, Call.getArgSVal(1)); - const llvm::APSInt *WhenceV = - C.getSValBuilder().getKnownValue(State, Call.getArgSVal(2)); - // Bifurcate the state into failed and non-failed. - // Return zero on success, nonzero on error. - ProgramStateRef StateNotFailed, StateFailed; - std::tie(StateFailed, StateNotFailed) = E.makeRetValAndAssumeDual(State, C); + // Return zero on success, -1 on error. + ProgramStateRef StateNotFailed = E.bindReturnValue(State, C, 0); + ProgramStateRef StateFailed = E.bindReturnValue(State, C, -1); // No failure: Reset the state to opened with no error. StateNotFailed = @@ -1282,12 +1277,10 @@ void StreamChecker::evalFseek(const FnDescription *Desc, const CallEvent &Call, // At error it is possible that fseek fails but sets none of the error flags. // If fseek failed, assume that the file position becomes indeterminate in any // case. - StreamErrorState NewErrS = ErrorNone | ErrorFError; - // Setting the position to start of file never produces EOF error. - if (!(PosV && *PosV == 0 && WhenceV && *WhenceV == SeekSetVal)) - NewErrS = NewErrS | ErrorFEof; - StateFailed = E.setStreamState(StateFailed, - StreamState::getOpened(Desc, NewErrS, true)); + // It is allowed to set the position beyond the end of the file. EOF error + // should not occur. + StateFailed = E.setStreamState( + StateFailed, StreamState::getOpened(Desc, ErrorNone | ErrorFError, true)); C.addTransition(StateFailed, E.getFailureNoteTag(this, C)); } diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index c3fc56ac30ee9f..7a900780384a91 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -330,7 +330,8 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, case CK_ConstructorConversion: case CK_UserDefinedConversion: case CK_FunctionToPointerDecay: - case CK_BuiltinFnToFnPtr: { + case CK_BuiltinFnToFnPtr: + case CK_HLSLArrayRValue: { // Copy the SVal of Ex to CastE. ProgramStateRef state = Pred->getState(); const LocationContext *LCtx = Pred->getLocationContext(); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 33b43417a6613d..492b8f1e2b3863 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -363,20 +363,22 @@ class DependencyScanningAction : public tooling::ToolAction { PrebuiltModuleVFSMap, ScanInstance.getDiagnostics())) return false; - // Use the dependency scanning optimized file system if requested to do so. - if (DepFS) { - llvm::IntrusiveRefCntPtr LocalDepFS = - DepFS; - ScanInstance.getPreprocessorOpts().DependencyDirectivesForFile = - [LocalDepFS = std::move(LocalDepFS)](FileEntryRef File) - -> std::optional> { - if (llvm::ErrorOr Entry = - LocalDepFS->getOrCreateFileSystemEntry(File.getName())) - if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry)) - return Entry->getDirectiveTokens(); - return std::nullopt; - }; - } + auto AdjustCI = [&](CompilerInstance &CI) { + // Set up the dependency scanning file system callback if requested. + if (DepFS) { + auto GetDependencyDirectives = [LocalDepFS = DepFS](FileEntryRef File) + -> std::optional> { + if (llvm::ErrorOr Entry = + LocalDepFS->getOrCreateFileSystemEntry(File.getName())) + if (LocalDepFS->ensureDirectiveTokensArePopulated(*Entry)) + return Entry->getDirectiveTokens(); + return std::nullopt; + }; + + CI.getPreprocessor().setDependencyDirectivesFn( + std::move(GetDependencyDirectives)); + } + }; // Create the dependency collector that will collect the produced // dependencies. @@ -428,9 +430,11 @@ class DependencyScanningAction : public tooling::ToolAction { std::unique_ptr Action; if (ModuleName) - Action = std::make_unique(*ModuleName); + Action = std::make_unique( + *ModuleName, std::move(AdjustCI)); else - Action = std::make_unique(); + Action = + std::make_unique(std::move(AdjustCI)); if (ScanInstance.getDiagnostics().hasErrorOccurred()) return false; diff --git a/clang/test/APINotes/Inputs/Headers/Templates.apinotes b/clang/test/APINotes/Inputs/Headers/Templates.apinotes new file mode 100644 index 00000000000000..b7336484da0c79 --- /dev/null +++ b/clang/test/APINotes/Inputs/Headers/Templates.apinotes @@ -0,0 +1,5 @@ +--- +Name: Templates +Tags: +- Name: Box + SwiftImportAs: owned diff --git a/clang/test/APINotes/Inputs/Headers/Templates.h b/clang/test/APINotes/Inputs/Headers/Templates.h new file mode 100644 index 00000000000000..862035fee363f7 --- /dev/null +++ b/clang/test/APINotes/Inputs/Headers/Templates.h @@ -0,0 +1,9 @@ +template +struct Box { + T value; + + const T& get_value() const { return value; } + const T* get_ptr() const { return &value; } +}; + +using IntBox = Box; diff --git a/clang/test/APINotes/Inputs/Headers/module.modulemap b/clang/test/APINotes/Inputs/Headers/module.modulemap index 99fb1aec86481a..d515169184f4f0 100644 --- a/clang/test/APINotes/Inputs/Headers/module.modulemap +++ b/clang/test/APINotes/Inputs/Headers/module.modulemap @@ -36,6 +36,10 @@ module Namespaces { header "Namespaces.h" } +module Templates { + header "Templates.h" +} + module SwiftImportAs { header "SwiftImportAs.h" } diff --git a/clang/test/APINotes/templates.cpp b/clang/test/APINotes/templates.cpp new file mode 100644 index 00000000000000..d4dce291615e18 --- /dev/null +++ b/clang/test/APINotes/templates.cpp @@ -0,0 +1,9 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Tmpl -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -x c++ +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Tmpl -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Box -x c++ | FileCheck -check-prefix=CHECK-BOX %s + +#include "Templates.h" + +// CHECK-BOX: Dumping Box: +// CHECK-BOX-NEXT: ClassTemplateDecl {{.+}} imported in Templates Box +// CHECK-BOX: SwiftAttrAttr {{.+}} <> "import_owned" diff --git a/clang/test/Analysis/stream-error.c b/clang/test/Analysis/stream-error.c index 88f7de4234ffb4..7f9116ff401445 100644 --- a/clang/test/Analysis/stream-error.c +++ b/clang/test/Analysis/stream-error.c @@ -365,27 +365,22 @@ void error_fseek(void) { return; int rc = fseek(F, 1, SEEK_SET); if (rc) { + clang_analyzer_eval(rc == -1); // expected-warning {{TRUE}} int IsFEof = feof(F), IsFError = ferror(F); - // Get feof or ferror or no error. - clang_analyzer_eval(IsFEof || IsFError); - // expected-warning@-1 {{FALSE}} - // expected-warning@-2 {{TRUE}} - clang_analyzer_eval(IsFEof && IsFError); // expected-warning {{FALSE}} + // Get ferror or no error. + clang_analyzer_eval(IsFError); // expected-warning {{FALSE}} \ + // expected-warning {{TRUE}} + clang_analyzer_eval(IsFEof); // expected-warning {{FALSE}} // Error flags should not change. - if (IsFEof) - clang_analyzer_eval(feof(F)); // expected-warning {{TRUE}} - else - clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} + clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} if (IsFError) - clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} - else - clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} + clang_analyzer_eval(ferror(F)); // expected-warning {{TRUE}} } else { - clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} - clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} + clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} + clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} // Error flags should not change. - clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} - clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} + clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} + clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} } fclose(F); } @@ -396,15 +391,13 @@ void error_fseeko(void) { return; int rc = fseeko(F, 1, SEEK_SET); if (rc) { - int IsFEof = feof(F), IsFError = ferror(F); - // Get feof or ferror or no error. - clang_analyzer_eval(IsFEof || IsFError); - // expected-warning@-1 {{FALSE}} - // expected-warning@-2 {{TRUE}} - clang_analyzer_eval(IsFEof && IsFError); // expected-warning {{FALSE}} + // Get ferror or no error. + clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} \ + // expected-warning {{TRUE}} + clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} } else { - clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} - clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} + clang_analyzer_eval(feof(F)); // expected-warning {{FALSE}} + clang_analyzer_eval(ferror(F)); // expected-warning {{FALSE}} } fclose(F); } @@ -414,7 +407,7 @@ void error_fseek_0(void) { if (!F) return; int rc = fseek(F, 0, SEEK_SET); - if (rc) { + if (rc == -1) { int IsFEof = feof(F), IsFError = ferror(F); // Get ferror or no error, but not feof. clang_analyzer_eval(IsFError); diff --git a/clang/test/Analysis/stream-note.c b/clang/test/Analysis/stream-note.c index f77cd4aa62841d..54ea699f46674e 100644 --- a/clang/test/Analysis/stream-note.c +++ b/clang/test/Analysis/stream-note.c @@ -226,10 +226,39 @@ void check_indeterminate_fseek(void) { return; int Ret = fseek(F, 1, SEEK_SET); // expected-note {{Assuming this stream operation fails}} if (Ret) { // expected-note {{Taking true branch}} \ - // expected-note {{'Ret' is not equal to 0}} + // expected-note {{'Ret' is -1}} char Buf[2]; fwrite(Buf, 1, 2, F); // expected-warning {{might be 'indeterminate'}} \ // expected-note {{might be 'indeterminate'}} } fclose(F); } + +void error_fseek_ftell(void) { + FILE *F = fopen("file", "r"); + if (!F) // expected-note {{Taking false branch}} \ + // expected-note {{'F' is non-null}} + return; + fseek(F, 0, SEEK_END); // expected-note {{Assuming this stream operation fails}} + long size = ftell(F); // expected-warning {{might be 'indeterminate'}} \ + // expected-note {{might be 'indeterminate'}} + if (size == -1) { + fclose(F); + return; + } + if (size == 1) + fprintf(F, "abcd"); + fclose(F); +} + +void error_fseek_read_eof(void) { + FILE *F = fopen("file", "r"); + if (!F) + return; + if (fseek(F, 22, SEEK_SET) == -1) { + fclose(F); + return; + } + fgetc(F); // no warning + fclose(F); +} diff --git a/clang/test/C/C2x/n2350.c b/clang/test/C/C2x/n2350.c index 2f738488a37427..af0ca6d79be5e1 100644 --- a/clang/test/C/C2x/n2350.c +++ b/clang/test/C/C2x/n2350.c @@ -5,7 +5,7 @@ // RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c99 -verify %s // RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c11 -verify %s // RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c17 -verify %s -// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c2x -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -Wno-comment -std=c2x -verify=silent %s // silent-no-diagnostics @@ -13,10 +13,10 @@ // https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm int simple(void) { return __builtin_offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \ - expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}} + expected-warning {{defining a type within '__builtin_offsetof' is a C23 extension}} { int a; - struct B // expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}} + struct B // expected-warning {{defining a type within '__builtin_offsetof' is a C23 extension}} { int c; int d; @@ -26,7 +26,7 @@ int simple(void) { int anonymous_struct(void) { return __builtin_offsetof(struct // cpp-error-re {{'(unnamed struct at {{.*}})' cannot be defined in a type specifier}} \ - expected-warning {{defining a type within '__builtin_offsetof' is a Clang extension}} + expected-warning {{defining a type within '__builtin_offsetof' is a C23 extension}} { int a; int b; @@ -47,7 +47,7 @@ int struct_in_second_param(void) { int macro(void) { return offsetof(struct A // cpp-error {{'A' cannot be defined in a type specifier}} \ - expected-warning 2 {{defining a type within 'offsetof' is a Clang extension}} + expected-warning 2 {{defining a type within 'offsetof' is a C23 extension}} { int a; struct B // verifier seems to think the error is emitted by the macro diff --git a/clang/test/C/C99/float_h-characteristics.c b/clang/test/C/C99/float_h-characteristics.c new file mode 100644 index 00000000000000..7e2a891ef87774 --- /dev/null +++ b/clang/test/C/C99/float_h-characteristics.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -verify -std=c99 -ffreestanding %s +// RUN: %clang_cc1 -verify -std=gnu89 -ffreestanding %s +// RUN: %clang_cc1 -verify -std=c89 -ffreestanding %s +// expected-no-diagnostics + +/* WG14 ???: Clang 16 + * Additional floating-point characteristics in + * + * NB: the original paper number is unknown, this was gleaned from the editor's + * report in the C99 foreword. There were two new additions to in + * C99, this is testing that we support both of them. + * + * Clang added the macros at least as far back as Clang 3.0, but it wasn't + * until Clang 16.0 that we stopped accidentally providing FLT_EVAL_METHOD in + * C89 (strict) mode. + */ + +#include + +// We expect all the definitions in C99 mode. +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define EXPECT_DECIMAL_DIG +#define EXPECT_FLT_EVAL_METHOD +#endif + +// If we're not in C99 mode, we still expect the definition of DECIMAL_DIG +// unless we're in strict ansi mode. +#if !defined(EXPECT_DECIMAL_DIG) && !defined(__STRICT_ANSI__) +#define EXPECT_DECIMAL_DIG +#endif + +#if defined(EXPECT_DECIMAL_DIG) + #if !defined(DECIMAL_DIG) + #error "DECIMAL_DIG missing" + #endif +#else + #if defined(DECIMAL_DIG) + #error "DECIMAL_DIG provided when not expected" + #endif +#endif + +#if defined(EXPECT_FLT_EVAL_METHOD) + #if !defined(FLT_EVAL_METHOD) + #error "FLT_EVAL_METHOD missing" + #endif +#else + #if defined(FLT_EVAL_METHOD) + #error "FLT_EVAL_METHOD provided when not expected" + #endif +#endif diff --git a/clang/test/C/C99/n570.c b/clang/test/C/C99/n570.c new file mode 100644 index 00000000000000..31c09224e618b5 --- /dev/null +++ b/clang/test/C/C99/n570.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -verify -std=c99 %s +// RUN: %clang_cc1 -E -std=c99 %s | FileCheck %s +// expected-no-diagnostics + +/* WG14 N570: Yes + * Empty macro arguments + * + * NB: the original paper is not available online anywhere, so the test + * coverage is coming from what could be gleaned from the C99 rationale + * document. In C89, it was UB to pass no arguments to a function-like macro, + * and that's now supported in C99. + */ + +#define TEN 10 +#define U u +#define I // expands into no preprocessing tokens +#define L L +#define glue(a, b) a ## b +#define xglue(a, b) glue(a, b) + +const unsigned u = xglue(TEN, U); +const int i = xglue(TEN, I); +const long l = xglue(TEN, L); + +// CHECK: const unsigned u = 10u; +// CHECK-NEXT: const int i = 10; +// CHECK-NEXT: const long l = 10L; + +_Static_assert(u == 10U, ""); +_Static_assert(i == 10, ""); +_Static_assert(l == 10L, ""); diff --git a/clang/test/C/C99/n782.c b/clang/test/C/C99/n782.c new file mode 100644 index 00000000000000..d147fd6fb1a1a2 --- /dev/null +++ b/clang/test/C/C99/n782.c @@ -0,0 +1,23 @@ +/* RUN: %clang_cc1 -verify -std=c99 -pedantic %s + RUN: %clang_cc1 -verify=c89 -std=c89 -pedantic %s + expected-no-diagnostics + */ + +/* WG14 N782: Clang 3.4 + * Relaxed constraints on aggregate and union initialization + */ + +void test(void) { + struct S { + int x, y; + }; + int a = 1, b = 2; + struct S s = { a, b }; /* c89-warning {{initializer for aggregate is not a compile-time constant}} */ + + union U { + int x; + float f; + }; + union U u = { a }; /* c89-warning {{initializer for aggregate is not a compile-time constant}} */ +} + diff --git a/clang/test/C/C99/n835.c b/clang/test/C/C99/n835.c new file mode 100644 index 00000000000000..38a974e065724d --- /dev/null +++ b/clang/test/C/C99/n835.c @@ -0,0 +1,35 @@ +/* RUN: %clang_cc1 -verify -pedantic -std=c99 %s + RUN: %clang_cc1 -verify=c89 -pedantic -std=c89 %s + expected-no-diagnostics + */ + +/* WG14 N835: Yes + * Conversion of array to pointer not limited to lvalues + * + * NB: The crux of the change was C99 changing: + * + * C89 3.2.2.1: Except when it is the operand of ..., an lvalue that has type + * 'array of type' is converted to an expression that has type 'pointer to + * type' that points to the initial element of the array object and is not an + * lvalue. + * + * C99 6.3.2.1p3: Except when it is the operand of ..., an expression that has + * type 'array of type' is converted to an expression with type 'pointer to + * type' that points to the initial element of the array object and is not an + * lvalue. + */ + +struct S { + char arr[100]; +}; + +struct S f(void); + +void func(void) { + char c; + /* The return from f() is an rvalue, so this code is not valid in C89, but is + * valid in C99. + */ + c = f().arr[10]; /* c89-warning {{ISO C90 does not allow subscripting non-lvalue array}} */ +} + diff --git a/clang/test/C/drs/dr4xx.c b/clang/test/C/drs/dr4xx.c index 30145dcfeef168..83d7b94cd67959 100644 --- a/clang/test/C/drs/dr4xx.c +++ b/clang/test/C/drs/dr4xx.c @@ -1,7 +1,7 @@ -/* RUN: %clang_cc1 -std=c89 -verify=expected,c89only -pedantic -Wno-c11-extensions %s - RUN: %clang_cc1 -std=c99 -verify=expected -pedantic -Wno-c11-extensions %s - RUN: %clang_cc1 -std=c11 -verify=expected -pedantic %s - RUN: %clang_cc1 -std=c17 -verify=expected -pedantic %s +/* RUN: %clang_cc1 -std=c89 -verify=expected,c89only,pre-c23 -pedantic -Wno-c11-extensions %s + RUN: %clang_cc1 -std=c99 -verify=expected,pre-c23 -pedantic -Wno-c11-extensions %s + RUN: %clang_cc1 -std=c11 -verify=expected,pre-c23 -pedantic %s + RUN: %clang_cc1 -std=c17 -verify=expected,pre-c23 -pedantic %s RUN: %clang_cc1 -std=c2x -verify=expected -pedantic %s */ @@ -343,10 +343,13 @@ void dr496(void) { */ /* The DR asked a question about whether defining a new type within offsetof - * is allowed. C2x N2350 made this explicitly undefined behavior, but GCC and - * Clang both support it as an extension. + * is allowed. C23 N2350 had made this explicitly undefined behavior, but this + * was later overturned when C23 DE-137 was accepted, making it well-formed. + * + * Additionally, GCC and Clang both support it as an extension in pre-C23 + * mode. */ - (void)__builtin_offsetof(struct S { int a; }, a); /* expected-warning{{defining a type within '__builtin_offsetof' is a Clang extension}} */ + (void)__builtin_offsetof(struct S { int a; }, a); /* pre-c23-warning{{defining a type within '__builtin_offsetof' is a C23 extension}} */ } /* WG14 DR499: yes diff --git a/clang/test/CXX/drs/dr16xx.cpp b/clang/test/CXX/drs/dr16xx.cpp index 766c90d3bc7bda..f4d6c04fb8e073 100644 --- a/clang/test/CXX/drs/dr16xx.cpp +++ b/clang/test/CXX/drs/dr16xx.cpp @@ -35,6 +35,17 @@ void g() { } } // namespace dr1601 +namespace dr1606 { // dr1606: 3.1 +#if __cplusplus >= 201103L + std::size_t test() { + int i = 1; + int j = 1; + auto f = [=]{ return i + j; }; + return sizeof(f); + } +#endif +} // namespace dr1606 + namespace dr1611 { // dr1611: dup 1658 struct A { A(int); }; struct B : virtual A { virtual void f() = 0; }; diff --git a/clang/test/CodeGen/M68k/inline-asm-gcc-regs.c b/clang/test/CodeGen/M68k/inline-asm-gcc-regs.c new file mode 100644 index 00000000000000..40d3543d8a6f90 --- /dev/null +++ b/clang/test/CodeGen/M68k/inline-asm-gcc-regs.c @@ -0,0 +1,134 @@ +// RUN: %clang_cc1 -triple m68k -emit-llvm -O2 %s -o - | FileCheck %s + +/// Check GCC register names and alias can be used in register variable definition. + +// CHECK-LABEL: @test_d0 +// CHECK: call void asm sideeffect "", "{d0}"(i32 undef) +void test_d0() { + register int a asm ("d0"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_d1 +// CHECK: call void asm sideeffect "", "{d1}"(i32 undef) +void test_d1() { + register int a asm ("d1"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_d2 +// CHECK: call void asm sideeffect "", "{d2}"(i32 undef) +void test_d2() { + register int a asm ("d2"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_d3 +// CHECK: call void asm sideeffect "", "{d3}"(i32 undef) +void test_d3() { + register int a asm ("d3"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_d4 +// CHECK: call void asm sideeffect "", "{d4}"(i32 undef) +void test_d4() { + register int a asm ("d4"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_d5 +// CHECK: call void asm sideeffect "", "{d5}"(i32 undef) +void test_d5() { + register int a asm ("d5"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_d6 +// CHECK: call void asm sideeffect "", "{d6}"(i32 undef) +void test_d6() { + register int a asm ("d6"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_d7 +// CHECK: call void asm sideeffect "", "{d7}"(i32 undef) +void test_d7() { + register int a asm ("d7"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_a0 +// CHECK: call void asm sideeffect "", "{a0}"(i32 undef) +void test_a0() { + register int a asm ("a0"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_a1 +// CHECK: call void asm sideeffect "", "{a1}"(i32 undef) +void test_a1() { + register int a asm ("a1"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_a2 +// CHECK: call void asm sideeffect "", "{a2}"(i32 undef) +void test_a2() { + register int a asm ("a2"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_a3 +// CHECK: call void asm sideeffect "", "{a3}"(i32 undef) +void test_a3() { + register int a asm ("a3"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_a4 +// CHECK: call void asm sideeffect "", "{a4}"(i32 undef) +void test_a4() { + register int a asm ("a4"); + asm ("" :: "r" (a)); +} + +// CHECK-LABEL: @test_a5 +// CHECK: call void asm sideeffect "", "{a5}"(i32 undef) +void test_a5() { + register int a asm ("a5"); + register int b asm ("bp"); + asm ("" :: "r" (a)); + asm ("" :: "r" (b)); +} + +// CHECK-LABEL: @test_a6 +// CHECK: call void asm sideeffect "", "{a6}"(i32 undef) +void test_a6() { + register int a asm ("a6"); + register int b asm ("fp"); + asm ("" :: "r" (a)); + asm ("" :: "r" (b)); +} + +// CHECK-LABEL: @test_sp +// CHECK: call void asm sideeffect "", "{sp}"(i32 undef) +void test_sp() { + register int a asm ("sp"); + register int b asm ("usp"); + register int c asm ("ssp"); + register int d asm ("isp"); + register int e asm ("a7"); + asm ("" :: "r" (a)); + asm ("" :: "r" (b)); + asm ("" :: "r" (c)); + asm ("" :: "r" (d)); + asm ("" :: "r" (e)); +} + +// CHECK-LABEL: @test_pc +// CHECK: call void asm sideeffect "", "{pc}"(i32 undef) +void test_pc() { + register int a asm ("pc"); + asm ("" :: "r" (a)); +} diff --git a/clang/test/CodeGen/aapcs-bitfield-access-unit.c b/clang/test/CodeGen/aapcs-bitfield-access-unit.c new file mode 100644 index 00000000000000..e95dba1c5f50cf --- /dev/null +++ b/clang/test/CodeGen/aapcs-bitfield-access-unit.c @@ -0,0 +1,231 @@ +// RUN: %clang_cc1 -triple armv8-none-linux-eabi -fno-aapcs-bitfield-width -fdump-record-layouts-simple -emit-llvm -o /dev/null %s | FileCheck %s -check-prefixes=LAYOUT +// RUN: %clang_cc1 -triple armebv8-none-linux-eabi -fno-aapcs-bitfield-width -fdump-record-layouts-simple -emit-llvm -o /dev/null %s | FileCheck %s -check-prefixes=LAYOUT + +// RUN: %clang_cc1 -triple armv8-none-linux-eabi -faapcs-bitfield-width -fdump-record-layouts-simple -emit-llvm -o /dev/null %s | FileCheck %s -check-prefixes=LAYOUT +// RUN: %clang_cc1 -triple armebv8-none-linux-eabi -faapcs-bitfield-width -fdump-record-layouts-simple -emit-llvm -o /dev/null %s | FileCheck %s -check-prefixes=LAYOUT + +struct st0 { + short c : 7; +} st0; +// LAYOUT-LABEL: LLVMType:%struct.st0 = +// LAYOUT-SAME: type { i8, i8 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st1 { + int a : 10; + short c : 6; +} st1; +// LAYOUT-LABEL: LLVMType:%struct.st1 = +// LAYOUT-SAME: type { i16, [2 x i8] } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st2 { + int a : 10; + short c : 7; +} st2; +// LAYOUT-LABEL: LLVMType:%struct.st2 = +// LAYOUT-SAME: type { i32 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st3 { + volatile short c : 7; +} st3; +// LAYOUT-LABEL: LLVMType:%struct.st3 = +// LAYOUT-SAME: type { i8, i8 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st4 { + int b : 9; + volatile char c : 5; +} st4; +// LAYOUT-LABEL: LLVMType:%struct.st4 = +// LAYOUT-SAME: type { i16, [2 x i8] } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st5 { + int a : 12; + volatile char c : 5; +} st5; +// LAYOUT-LABEL: LLVMType:%struct.st5 = +// LAYOUT-SAME: type { i32 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st6 { + int a : 12; + char b; + int c : 5; +} st6; +// LAYOUT-LABEL: LLVMType:%struct.st6 = +// LAYOUT-SAME: type { i16, i8, i8 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st7a { + char a; + int b : 5; +} st7a; +// LAYOUT-LABEL: LLVMType:%struct.st7a = +// LAYOUT-SAME: type { i8, i8, [2 x i8] } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st7b { + char x; + volatile struct st7a y; +} st7b; +// LAYOUT-LABEL: LLVMType:%struct.st7b = +// LAYOUT-SAME: type { i8, [3 x i8], %struct.st7a } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: ]> + +struct st8 { + unsigned f : 16; +} st8; +// LAYOUT-LABEL: LLVMType:%struct.st8 = +// LAYOUT-SAME: type { i16, [2 x i8] } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st9{ + int f : 8; +} st9; +// LAYOUT-LABEL: LLVMType:%struct.st9 = +// LAYOUT-SAME: type { i8, [3 x i8] } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st10{ + int e : 1; + int f : 8; +} st10; +// LAYOUT-LABEL: LLVMType:%struct.st10 = +// LAYOUT-SAME: type { i16, [2 x i8] } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st11{ + char e; + int f : 16; +} st11; +// LAYOUT-LABEL: LLVMType:%struct.st11 = +// LAYOUT-SAME: type <{ i8, i16, i8 }> +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st12{ + int e : 8; + int f : 16; +} st12; +// LAYOUT-LABEL: LLVMType:%struct.st12 = +// LAYOUT-SAME: type { i32 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st13 { + char a : 8; + int b : 32; +} __attribute__((packed)) st13; +// LAYOUT-LABEL: LLVMType:%struct.st13 = +// LAYOUT-SAME: type <{ i8, i32 }> +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st14 { + char a : 8; +} __attribute__((packed)) st14; +// LAYOUT-LABEL: LLVMType:%struct.st14 = +// LAYOUT-SAME: type { i8 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st15 { + short a : 8; +} __attribute__((packed)) st15; +// LAYOUT-LABEL: LLVMType:%struct.st15 = +// LAYOUT-SAME: type { i8 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st16 { + int a : 32; + int b : 16; + int c : 32; + int d : 16; +} st16; +// LAYOUT-LABEL: LLVMType:%struct.st16 = +// LAYOUT-SAME: type { i32, i16, i32, i16 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct st17 { +int b : 32; +char c : 8; +} __attribute__((packed)) st17; +// LAYOUT-LABEL: LLVMType:%struct.st17 = +// LAYOUT-SAME: type <{ i32, i8 }> +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct zero_bitfield { + int a : 8; + char : 0; + int b : 8; +} st18; +// LAYOUT-LABEL: LLVMType:%struct.zero_bitfield = +// LAYOUT-SAME: type { i8, i8, [2 x i8] } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + +struct zero_bitfield_ok { + short a : 8; + char a1 : 8; + long : 0; + int b : 24; +} st19; +// LAYOUT-LABEL: LLVMType:%struct.zero_bitfield_ok = +// LAYOUT-SAME: type { i16, i32 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + + diff --git a/clang/test/CodeGen/aapcs-bitfield.c b/clang/test/CodeGen/aapcs-bitfield.c index 152ee26e7a3ea9..0df250d4ebc53e 100644 --- a/clang/test/CodeGen/aapcs-bitfield.c +++ b/clang/test/CodeGen/aapcs-bitfield.c @@ -299,77 +299,73 @@ struct st2 { // LE-LABEL: @st2_check_load( // LE-NEXT: entry: -// LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LE-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// LE-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 1 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 1 -// LE-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i16 +// LE-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// LE-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 9 +// LE-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 25 +// LE-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i16 // LE-NEXT: [[CONV:%.*]] = sext i16 [[BF_CAST]] to i32 // LE-NEXT: ret i32 [[CONV]] // // BE-LABEL: @st2_check_load( // BE-NEXT: entry: -// BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BE-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 1 -// BE-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i16 +// BE-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// BE-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 +// BE-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 25 +// BE-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i16 // BE-NEXT: [[CONV:%.*]] = sext i16 [[BF_CAST]] to i32 // BE-NEXT: ret i32 [[CONV]] // // LENUMLOADS-LABEL: @st2_check_load( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 1 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 1 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i16 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 9 +// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 25 +// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i16 // LENUMLOADS-NEXT: [[CONV:%.*]] = sext i16 [[BF_CAST]] to i32 // LENUMLOADS-NEXT: ret i32 [[CONV]] // // BENUMLOADS-LABEL: @st2_check_load( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 1 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i16 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 +// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 25 +// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i16 // BENUMLOADS-NEXT: [[CONV:%.*]] = sext i16 [[BF_CAST]] to i32 // BENUMLOADS-NEXT: ret i32 [[CONV]] // // LEWIDTH-LABEL: @st2_check_load( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 1 -// LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 1 -// LEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i16 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 9 +// LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 25 +// LEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i16 // LEWIDTH-NEXT: [[CONV:%.*]] = sext i16 [[BF_CAST]] to i32 // LEWIDTH-NEXT: ret i32 [[CONV]] // // BEWIDTH-LABEL: @st2_check_load( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 1 -// BEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i16 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 +// BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 25 +// BEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i16 // BEWIDTH-NEXT: [[CONV:%.*]] = sext i16 [[BF_CAST]] to i32 // BEWIDTH-NEXT: ret i32 [[CONV]] // // LEWIDTHNUM-LABEL: @st2_check_load( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 1 -// LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 1 -// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i16 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 9 +// LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 25 +// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i16 // LEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i16 [[BF_CAST]] to i32 // LEWIDTHNUM-NEXT: ret i32 [[CONV]] // // BEWIDTHNUM-LABEL: @st2_check_load( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 1 -// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_ASHR]] to i16 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 +// BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 25 +// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i16 // BEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i16 [[BF_CAST]] to i32 // BEWIDTHNUM-NEXT: ret i32 [[CONV]] // @@ -379,74 +375,66 @@ int st2_check_load(struct st2 *m) { // LE-LABEL: @st2_check_store( // LE-NEXT: entry: -// LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LE-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -128 -// LE-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1 -// LE-NEXT: store i8 [[BF_SET]], ptr [[C]], align 2 +// LE-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// LE-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -8323073 +// LE-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 65536 +// LE-NEXT: store i32 [[BF_SET]], ptr [[M]], align 4 // LE-NEXT: ret void // // BE-LABEL: @st2_check_store( // BE-NEXT: entry: -// BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BE-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 1 -// BE-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 2 -// BE-NEXT: store i8 [[BF_SET]], ptr [[C]], align 2 +// BE-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// BE-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -65025 +// BE-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 512 +// BE-NEXT: store i32 [[BF_SET]], ptr [[M]], align 4 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @st2_check_store( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -128 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1 -// LENUMLOADS-NEXT: store i8 [[BF_SET]], ptr [[C]], align 2 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -8323073 +// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 65536 +// LENUMLOADS-NEXT: store i32 [[BF_SET]], ptr [[M]], align 4 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @st2_check_store( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 1 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 2 -// BENUMLOADS-NEXT: store i8 [[BF_SET]], ptr [[C]], align 2 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -65025 +// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 512 +// BENUMLOADS-NEXT: store i32 [[BF_SET]], ptr [[M]], align 4 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @st2_check_store( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -128 -// LEWIDTH-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1 -// LEWIDTH-NEXT: store i8 [[BF_SET]], ptr [[C]], align 2 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -8323073 +// LEWIDTH-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 65536 +// LEWIDTH-NEXT: store i32 [[BF_SET]], ptr [[M]], align 4 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @st2_check_store( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 1 -// BEWIDTH-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 2 -// BEWIDTH-NEXT: store i8 [[BF_SET]], ptr [[C]], align 2 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -65025 +// BEWIDTH-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 512 +// BEWIDTH-NEXT: store i32 [[BF_SET]], ptr [[M]], align 4 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @st2_check_store( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -128 -// LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1 -// LEWIDTHNUM-NEXT: store i8 [[BF_SET]], ptr [[C]], align 2 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -8323073 +// LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 65536 +// LEWIDTHNUM-NEXT: store i32 [[BF_SET]], ptr [[M]], align 4 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @st2_check_store( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST2:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[C]], align 2 -// BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 1 -// BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 2 -// BEWIDTHNUM-NEXT: store i8 [[BF_SET]], ptr [[C]], align 2 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[M:%.*]], align 4 +// BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -65025 +// BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 512 +// BEWIDTHNUM-NEXT: store i32 [[BF_SET]], ptr [[M]], align 4 // BEWIDTHNUM-NEXT: ret void // void st2_check_store(struct st2 *m) { @@ -636,8 +624,8 @@ struct st4 { // // LEWIDTH-LABEL: @st4_check_load( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// LEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 2 // LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 3 // LEWIDTH-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 @@ -645,8 +633,8 @@ struct st4 { // // BEWIDTH-LABEL: @st4_check_load( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// BEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 1 // BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 3 // BEWIDTH-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 @@ -654,8 +642,8 @@ struct st4 { // // LEWIDTHNUM-LABEL: @st4_check_load( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 2 // LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 3 // LEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 @@ -663,8 +651,8 @@ struct st4 { // // BEWIDTHNUM-LABEL: @st4_check_load( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 1 // BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 3 // BEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 @@ -708,38 +696,38 @@ int st4_check_load(struct st4 *m) { // // LEWIDTH-LABEL: @st4_check_store( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// LEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -63 // LEWIDTH-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 2 -// LEWIDTH-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP1]], align 1 +// LEWIDTH-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP0]], align 1 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @st4_check_store( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// BEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -125 // BEWIDTH-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 4 -// BEWIDTH-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP1]], align 1 +// BEWIDTH-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP0]], align 1 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @st4_check_store( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -63 // LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 2 -// LEWIDTHNUM-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP1]], align 1 +// LEWIDTHNUM-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP0]], align 1 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @st4_check_store( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -125 // BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 4 -// BEWIDTHNUM-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP1]], align 1 +// BEWIDTHNUM-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP0]], align 1 // BEWIDTHNUM-NEXT: ret void // void st4_check_store(struct st4 *m) { @@ -821,42 +809,44 @@ struct st5 { // LE-LABEL: @st5_check_load( // LE-NEXT: entry: -// LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 -// LE-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 3 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 3 -// LE-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 +// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[M:%.*]], align 4 +// LE-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 11 +// LE-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 27 +// LE-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i8 +// LE-NEXT: [[CONV:%.*]] = sext i8 [[BF_CAST]] to i32 // LE-NEXT: ret i32 [[CONV]] // // BE-LABEL: @st5_check_load( // BE-NEXT: entry: -// BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 3 -// BE-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 +// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[M:%.*]], align 4 +// BE-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 +// BE-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 27 +// BE-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i8 +// BE-NEXT: [[CONV:%.*]] = sext i8 [[BF_CAST]] to i32 // BE-NEXT: ret i32 [[CONV]] // // LENUMLOADS-LABEL: @st5_check_load( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 3 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 3 -// LENUMLOADS-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[M:%.*]], align 4 +// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 11 +// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 27 +// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i8 +// LENUMLOADS-NEXT: [[CONV:%.*]] = sext i8 [[BF_CAST]] to i32 // LENUMLOADS-NEXT: ret i32 [[CONV]] // // BENUMLOADS-LABEL: @st5_check_load( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 3 -// BENUMLOADS-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[M:%.*]], align 4 +// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 +// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 27 +// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i32 [[BF_ASHR]] to i8 +// BENUMLOADS-NEXT: [[CONV:%.*]] = sext i8 [[BF_CAST]] to i32 // BENUMLOADS-NEXT: ret i32 [[CONV]] // // LEWIDTH-LABEL: @st5_check_load( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 +// LEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 2 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 2 // LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 3 // LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 3 // LEWIDTH-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 @@ -864,16 +854,16 @@ struct st5 { // // BEWIDTH-LABEL: @st5_check_load( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 +// BEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 2 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 2 // BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 3 // BEWIDTH-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 // BEWIDTH-NEXT: ret i32 [[CONV]] // // LEWIDTHNUM-LABEL: @st5_check_load( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 2 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 2 // LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i8 [[BF_LOAD]], 3 // LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_SHL]], 3 // LEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 @@ -881,8 +871,8 @@ struct st5 { // // BEWIDTHNUM-LABEL: @st5_check_load( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 2 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 2 // BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i8 [[BF_LOAD]], 3 // BEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i8 [[BF_ASHR]] to i32 // BEWIDTHNUM-NEXT: ret i32 [[CONV]] @@ -893,74 +883,70 @@ int st5_check_load(struct st5 *m) { // LE-LABEL: @st5_check_store( // LE-NEXT: entry: -// LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -32 -// LE-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1 -// LE-NEXT: store volatile i8 [[BF_SET]], ptr [[C]], align 2 +// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[M:%.*]], align 4 +// LE-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -2031617 +// LE-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 65536 +// LE-NEXT: store volatile i32 [[BF_SET]], ptr [[M]], align 4 // LE-NEXT: ret void // // BE-LABEL: @st5_check_store( // BE-NEXT: entry: -// BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 7 -// BE-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 8 -// BE-NEXT: store volatile i8 [[BF_SET]], ptr [[C]], align 2 +// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[M:%.*]], align 4 +// BE-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -63489 +// BE-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 2048 +// BE-NEXT: store volatile i32 [[BF_SET]], ptr [[M]], align 4 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @st5_check_store( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -32 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1 -// LENUMLOADS-NEXT: store volatile i8 [[BF_SET]], ptr [[C]], align 2 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[M:%.*]], align 4 +// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -2031617 +// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 65536 +// LENUMLOADS-NEXT: store volatile i32 [[BF_SET]], ptr [[M]], align 4 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @st5_check_store( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 7 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 8 -// BENUMLOADS-NEXT: store volatile i8 [[BF_SET]], ptr [[C]], align 2 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[M:%.*]], align 4 +// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -63489 +// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], 2048 +// BENUMLOADS-NEXT: store volatile i32 [[BF_SET]], ptr [[M]], align 4 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @st5_check_store( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 +// LEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 2 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 2 // LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -32 // LEWIDTH-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1 -// LEWIDTH-NEXT: store volatile i8 [[BF_SET]], ptr [[C]], align 2 +// LEWIDTH-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP0]], align 2 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @st5_check_store( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 +// BEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 2 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 2 // BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 7 // BEWIDTH-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 8 -// BEWIDTH-NEXT: store volatile i8 [[BF_SET]], ptr [[C]], align 2 +// BEWIDTH-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP0]], align 2 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @st5_check_store( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 2 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 2 // LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], -32 // LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 1 -// LEWIDTHNUM-NEXT: store volatile i8 [[BF_SET]], ptr [[C]], align 2 +// LEWIDTHNUM-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP0]], align 2 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @st5_check_store( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST5:%.*]], ptr [[M:%.*]], i32 0, i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 2 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[M:%.*]], i32 2 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP0]], align 2 // BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i8 [[BF_LOAD]], 7 // BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i8 [[BF_CLEAR]], 8 -// BEWIDTHNUM-NEXT: store volatile i8 [[BF_SET]], ptr [[C]], align 2 +// BEWIDTHNUM-NEXT: store volatile i8 [[BF_SET]], ptr [[TMP0]], align 2 // BEWIDTHNUM-NEXT: ret void // void st5_check_store(struct st5 *m) { @@ -980,8 +966,8 @@ struct st6 { // LE-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 4 // LE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // LE-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6:%.*]], ptr [[M]], i32 0, i32 1 -// LE-NEXT: [[TMP1:%.*]] = load volatile i8, ptr [[B]], align 2 -// LE-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32 +// LE-NEXT: [[TMP0:%.*]] = load volatile i8, ptr [[B]], align 2 +// LE-NEXT: [[CONV:%.*]] = sext i8 [[TMP0]] to i32 // LE-NEXT: [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]] // LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], ptr [[M]], i32 0, i32 2 // LE-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 @@ -997,8 +983,8 @@ struct st6 { // BE-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_LOAD]], 4 // BE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // BE-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6:%.*]], ptr [[M]], i32 0, i32 1 -// BE-NEXT: [[TMP1:%.*]] = load volatile i8, ptr [[B]], align 2 -// BE-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32 +// BE-NEXT: [[TMP0:%.*]] = load volatile i8, ptr [[B]], align 2 +// BE-NEXT: [[CONV:%.*]] = sext i8 [[TMP0]] to i32 // BE-NEXT: [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]] // BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], ptr [[M]], i32 0, i32 2 // BE-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 @@ -1014,8 +1000,8 @@ struct st6 { // LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 4 // LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // LENUMLOADS-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6:%.*]], ptr [[M]], i32 0, i32 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = load volatile i8, ptr [[B]], align 2 -// LENUMLOADS-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = load volatile i8, ptr [[B]], align 2 +// LENUMLOADS-NEXT: [[CONV:%.*]] = sext i8 [[TMP0]] to i32 // LENUMLOADS-NEXT: [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]] // LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], ptr [[M]], i32 0, i32 2 // LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 @@ -1031,8 +1017,8 @@ struct st6 { // BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_LOAD]], 4 // BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // BENUMLOADS-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6:%.*]], ptr [[M]], i32 0, i32 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = load volatile i8, ptr [[B]], align 2 -// BENUMLOADS-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = load volatile i8, ptr [[B]], align 2 +// BENUMLOADS-NEXT: [[CONV:%.*]] = sext i8 [[TMP0]] to i32 // BENUMLOADS-NEXT: [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]] // BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], ptr [[M]], i32 0, i32 2 // BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 @@ -1048,8 +1034,8 @@ struct st6 { // LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 4 // LEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // LEWIDTH-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6:%.*]], ptr [[M]], i32 0, i32 1 -// LEWIDTH-NEXT: [[TMP1:%.*]] = load volatile i8, ptr [[B]], align 2 -// LEWIDTH-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32 +// LEWIDTH-NEXT: [[TMP0:%.*]] = load volatile i8, ptr [[B]], align 2 +// LEWIDTH-NEXT: [[CONV:%.*]] = sext i8 [[TMP0]] to i32 // LEWIDTH-NEXT: [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]] // LEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], ptr [[M]], i32 0, i32 2 // LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 @@ -1065,8 +1051,8 @@ struct st6 { // BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_LOAD]], 4 // BEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // BEWIDTH-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6:%.*]], ptr [[M]], i32 0, i32 1 -// BEWIDTH-NEXT: [[TMP1:%.*]] = load volatile i8, ptr [[B]], align 2 -// BEWIDTH-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32 +// BEWIDTH-NEXT: [[TMP0:%.*]] = load volatile i8, ptr [[B]], align 2 +// BEWIDTH-NEXT: [[CONV:%.*]] = sext i8 [[TMP0]] to i32 // BEWIDTH-NEXT: [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]] // BEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], ptr [[M]], i32 0, i32 2 // BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 @@ -1082,8 +1068,8 @@ struct st6 { // LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 4 // LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // LEWIDTHNUM-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6:%.*]], ptr [[M]], i32 0, i32 1 -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = load volatile i8, ptr [[B]], align 2 -// LEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = load volatile i8, ptr [[B]], align 2 +// LEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i8 [[TMP0]] to i32 // LEWIDTHNUM-NEXT: [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]] // LEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], ptr [[M]], i32 0, i32 2 // LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 @@ -1099,8 +1085,8 @@ struct st6 { // BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_LOAD]], 4 // BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // BEWIDTHNUM-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST6:%.*]], ptr [[M]], i32 0, i32 1 -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = load volatile i8, ptr [[B]], align 2 -// BEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i8 [[TMP1]] to i32 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = load volatile i8, ptr [[B]], align 2 +// BEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i8 [[TMP0]] to i32 // BEWIDTHNUM-NEXT: [[ADD:%.*]] = add nsw i32 [[BF_CAST]], [[CONV]] // BEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST6]], ptr [[M]], i32 0, i32 2 // BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 @@ -1704,9 +1690,9 @@ void store_st9(volatile struct st9 *m) { // LE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[M:%.*]], align 4 // LE-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 -// LE-NEXT: store volatile i8 [[TMP1]], ptr [[M]], align 4 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// LE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 +// LE-NEXT: store volatile i8 [[TMP0]], ptr [[M]], align 4 +// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // LE-NEXT: ret void // // BE-LABEL: @increment_st9( @@ -1714,9 +1700,9 @@ void store_st9(volatile struct st9 *m) { // BE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[M:%.*]], align 4 // BE-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 -// BE-NEXT: store volatile i8 [[TMP1]], ptr [[M]], align 4 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// BE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 +// BE-NEXT: store volatile i8 [[TMP0]], ptr [[M]], align 4 +// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_st9( @@ -1724,10 +1710,10 @@ void store_st9(volatile struct st9 *m) { // LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[M:%.*]], align 4 // LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 // LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[M]], align 4 -// LENUMLOADS-NEXT: store volatile i8 [[TMP1]], ptr [[M]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// LENUMLOADS-NEXT: store volatile i8 [[TMP0]], ptr [[M]], align 4 +// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_st9( @@ -1735,10 +1721,10 @@ void store_st9(volatile struct st9 *m) { // BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[M:%.*]], align 4 // BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 // BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[M]], align 4 -// BENUMLOADS-NEXT: store volatile i8 [[TMP1]], ptr [[M]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// BENUMLOADS-NEXT: store volatile i8 [[TMP0]], ptr [[M]], align 4 +// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_st9( @@ -1949,9 +1935,9 @@ void store_st10(volatile struct st10 *m) { // LE-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8 // LE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i16 +// LE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 // LE-NEXT: [[BF_LOAD1:%.*]] = load volatile i16, ptr [[M]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP1]], 255 +// LE-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP0]], 255 // LE-NEXT: [[BF_SHL2:%.*]] = shl i16 [[BF_VALUE]], 1 // LE-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD1]], -511 // LE-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_SHL2]] @@ -1968,9 +1954,9 @@ void store_st10(volatile struct st10 *m) { // BE-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8 // BE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i16 +// BE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 // BE-NEXT: [[BF_LOAD1:%.*]] = load volatile i16, ptr [[M]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP1]], 255 +// BE-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP0]], 255 // BE-NEXT: [[BF_SHL2:%.*]] = shl i16 [[BF_VALUE]], 7 // BE-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD1]], -32641 // BE-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_SHL2]] @@ -1987,9 +1973,9 @@ void store_st10(volatile struct st10 *m) { // LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8 // LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i16 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 // LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i16, ptr [[M]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP1]], 255 +// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP0]], 255 // LENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i16 [[BF_VALUE]], 1 // LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD1]], -511 // LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_SHL2]] @@ -2006,9 +1992,9 @@ void store_st10(volatile struct st10 *m) { // BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8 // BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_ASHR]] to i32 // BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i16 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 // BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i16, ptr [[M]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP1]], 255 +// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP0]], 255 // BENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i16 [[BF_VALUE]], 7 // BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD1]], -32641 // BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_SHL2]] @@ -2767,146 +2753,70 @@ struct st13 { // LE-LABEL: @increment_b_st13( // LE-NEXT: entry: -// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 8 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// LE-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LE-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// LE-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255 -// LE-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// LE-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST13:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[B]], align 1 +// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LE-NEXT: store volatile i32 [[INC]], ptr [[B]], align 1 // LE-NEXT: ret void // // BE-LABEL: @increment_b_st13( // BE-NEXT: entry: -// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BE-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 8 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 8 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// BE-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BE-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296 -// BE-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// BE-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST13:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[B]], align 1 +// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BE-NEXT: store volatile i32 [[INC]], ptr [[B]], align 1 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_b_st13( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 8 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// LENUMLOADS-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST13:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[B]], align 1 +// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[B]], align 1 +// LENUMLOADS-NEXT: store volatile i32 [[INC]], ptr [[B]], align 1 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_b_st13( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 8 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 8 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// BENUMLOADS-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST13:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[B]], align 1 +// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[B]], align 1 +// BENUMLOADS-NEXT: store volatile i32 [[INC]], ptr [[B]], align 1 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_b_st13( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 8 -// LEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255 -// LEWIDTH-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// LEWIDTH-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// LEWIDTH-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST13:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[B]], align 1 +// LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LEWIDTH-NEXT: store volatile i32 [[INC]], ptr [[B]], align 1 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_b_st13( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 8 -// BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 8 -// BEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296 -// BEWIDTH-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// BEWIDTH-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// BEWIDTH-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST13:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[B]], align 1 +// BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BEWIDTH-NEXT: store volatile i32 [[INC]], ptr [[B]], align 1 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_b_st13( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 8 -// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255 -// LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// LEWIDTHNUM-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// LEWIDTHNUM-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST13:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[B]], align 1 +// LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[B]], align 1 +// LEWIDTHNUM-NEXT: store volatile i32 [[INC]], ptr [[B]], align 1 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_b_st13( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 8 -// BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 8 -// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296 -// BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// BEWIDTHNUM-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// BEWIDTHNUM-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST13:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[B]], align 1 +// BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[B]], align 1 +// BEWIDTHNUM-NEXT: store volatile i32 [[INC]], ptr [[B]], align 1 // BEWIDTHNUM-NEXT: ret void // void increment_b_st13(volatile struct st13 *s) { @@ -2990,9 +2900,9 @@ struct st15 { // LE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 1 // LE-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i16 // LE-NEXT: [[INC:%.*]] = add i16 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = trunc i16 [[INC]] to i8 -// LE-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 1 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i16 +// LE-NEXT: [[TMP0:%.*]] = trunc i16 [[INC]] to i8 +// LE-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 1 +// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i16 // LE-NEXT: ret void // // BE-LABEL: @increment_a_st15( @@ -3000,9 +2910,9 @@ struct st15 { // BE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 1 // BE-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i16 // BE-NEXT: [[INC:%.*]] = add i16 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = trunc i16 [[INC]] to i8 -// BE-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 1 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i16 +// BE-NEXT: [[TMP0:%.*]] = trunc i16 [[INC]] to i8 +// BE-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 1 +// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i16 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_a_st15( @@ -3010,10 +2920,10 @@ struct st15 { // LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 1 // LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i16 // LENUMLOADS-NEXT: [[INC:%.*]] = add i16 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = trunc i16 [[INC]] to i8 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i16 [[INC]] to i8 // LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[S]], align 1 -// LENUMLOADS-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 1 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i16 +// LENUMLOADS-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 1 +// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i16 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_a_st15( @@ -3021,10 +2931,10 @@ struct st15 { // BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 1 // BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i16 // BENUMLOADS-NEXT: [[INC:%.*]] = add i16 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = trunc i16 [[INC]] to i8 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i16 [[INC]] to i8 // BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[S]], align 1 -// BENUMLOADS-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 1 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i16 +// BENUMLOADS-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 1 +// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i16 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_a_st15( @@ -3032,9 +2942,9 @@ struct st15 { // LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 1 // LEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i16 // LEWIDTH-NEXT: [[INC:%.*]] = add i16 [[BF_CAST]], 1 -// LEWIDTH-NEXT: [[TMP1:%.*]] = trunc i16 [[INC]] to i8 -// LEWIDTH-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 1 -// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i16 +// LEWIDTH-NEXT: [[TMP0:%.*]] = trunc i16 [[INC]] to i8 +// LEWIDTH-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 1 +// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i16 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_a_st15( @@ -3042,9 +2952,9 @@ struct st15 { // BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 1 // BEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i16 // BEWIDTH-NEXT: [[INC:%.*]] = add i16 [[BF_CAST]], 1 -// BEWIDTH-NEXT: [[TMP1:%.*]] = trunc i16 [[INC]] to i8 -// BEWIDTH-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 1 -// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i16 +// BEWIDTH-NEXT: [[TMP0:%.*]] = trunc i16 [[INC]] to i8 +// BEWIDTH-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 1 +// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i16 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_a_st15( @@ -3052,10 +2962,10 @@ struct st15 { // LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 1 // LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i16 // LEWIDTHNUM-NEXT: [[INC:%.*]] = add i16 [[BF_CAST]], 1 -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = trunc i16 [[INC]] to i8 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = trunc i16 [[INC]] to i8 // LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[S]], align 1 -// LEWIDTHNUM-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 1 -// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i16 +// LEWIDTHNUM-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 1 +// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i16 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_a_st15( @@ -3063,10 +2973,10 @@ struct st15 { // BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 1 // BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i16 // BEWIDTHNUM-NEXT: [[INC:%.*]] = add i16 [[BF_CAST]], 1 -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = trunc i16 [[INC]] to i8 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = trunc i16 [[INC]] to i8 // BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[S]], align 1 -// BEWIDTHNUM-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 1 -// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i16 +// BEWIDTHNUM-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 1 +// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i16 // BEWIDTHNUM-NEXT: ret void // void increment_a_st15(volatile struct st15 *s) { @@ -3082,146 +2992,58 @@ struct st16 { // LE-LABEL: @increment_a_st16( // LE-NEXT: entry: -// LE-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// LE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LE-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LE-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[S:%.*]], align 4 +// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LE-NEXT: store i32 [[INC]], ptr [[S]], align 4 // LE-NEXT: ret void // // BE-LABEL: @increment_a_st16( // BE-NEXT: entry: -// BE-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BE-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BE-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[S:%.*]], align 4 +// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BE-NEXT: store i32 [[INC]], ptr [[S]], align 4 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_a_st16( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LENUMLOADS-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[S:%.*]], align 4 +// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LENUMLOADS-NEXT: store i32 [[INC]], ptr [[S]], align 4 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_a_st16( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BENUMLOADS-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[S:%.*]], align 4 +// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BENUMLOADS-NEXT: store i32 [[INC]], ptr [[S]], align 4 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_a_st16( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// LEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LEWIDTH-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTH-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// LEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[S:%.*]], align 4 +// LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LEWIDTH-NEXT: store i32 [[INC]], ptr [[S]], align 4 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_a_st16( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// BEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BEWIDTH-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTH-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// BEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[S:%.*]], align 4 +// BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BEWIDTH-NEXT: store i32 [[INC]], ptr [[S]], align 4 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_a_st16( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// LEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTHNUM-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// LEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[S:%.*]], align 4 +// LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LEWIDTHNUM-NEXT: store i32 [[INC]], ptr [[S]], align 4 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_a_st16( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// BEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTHNUM-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// BEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[S:%.*]], align 4 +// BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BEWIDTHNUM-NEXT: store i32 [[INC]], ptr [[S]], align 4 // BEWIDTHNUM-NEXT: ret void // void increment_a_st16(struct st16 *s) { @@ -3230,154 +3052,90 @@ void increment_a_st16(struct st16 *s) { // LE-LABEL: @increment_b_st16( // LE-NEXT: entry: -// LE-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// LE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LE-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LE-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[B]], align 4 +// LE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LE-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LE-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LE-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LE-NEXT: store i16 [[TMP0]], ptr [[B]], align 4 +// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LE-NEXT: ret void // // BE-LABEL: @increment_b_st16( // BE-NEXT: entry: -// BE-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// BE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BE-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BE-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[B]], align 4 +// BE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BE-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BE-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BE-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BE-NEXT: store i16 [[TMP0]], ptr [[B]], align 4 +// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_b_st16( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LENUMLOADS-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[B]], align 4 +// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LENUMLOADS-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LENUMLOADS-NEXT: store i16 [[TMP0]], ptr [[B]], align 4 +// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_b_st16( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BENUMLOADS-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[B]], align 4 +// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BENUMLOADS-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BENUMLOADS-NEXT: store i16 [[TMP0]], ptr [[B]], align 4 +// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_b_st16( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LEWIDTH-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[B]], align 4 +// LEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// LEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LEWIDTH-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LEWIDTH-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LEWIDTH-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// LEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LEWIDTH-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LEWIDTH-NEXT: store i16 [[TMP0]], ptr [[B]], align 4 +// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_b_st16( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BEWIDTH-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[B]], align 4 +// BEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// BEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BEWIDTH-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BEWIDTH-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BEWIDTH-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// BEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BEWIDTH-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BEWIDTH-NEXT: store i16 [[TMP0]], ptr [[B]], align 4 +// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_b_st16( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LEWIDTHNUM-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[B]], align 4 +// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// LEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LEWIDTHNUM-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LEWIDTHNUM-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// LEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LEWIDTHNUM-NEXT: store i16 [[TMP0]], ptr [[B]], align 4 +// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_b_st16( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[S:%.*]], align 4 -// BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BEWIDTHNUM-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[B]], align 4 +// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[S]], align 4 -// BEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BEWIDTHNUM-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BEWIDTHNUM-NEXT: store i64 [[BF_SET]], ptr [[S]], align 4 -// BEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BEWIDTHNUM-NEXT: store i16 [[TMP0]], ptr [[B]], align 4 +// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BEWIDTHNUM-NEXT: ret void // void increment_b_st16(struct st16 *s) { @@ -3386,154 +3144,66 @@ void increment_b_st16(struct st16 *s) { // LE-LABEL: @increment_c_st16( // LE-NEXT: entry: -// LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LE-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[C]], align 4 -// LE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LE-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[C]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LE-NEXT: store i64 [[BF_SET]], ptr [[C]], align 4 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// LE-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[C]], align 4 +// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LE-NEXT: store i32 [[INC]], ptr [[C]], align 4 // LE-NEXT: ret void // // BE-LABEL: @increment_c_st16( // BE-NEXT: entry: -// BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BE-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[C]], align 4 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BE-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[C]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BE-NEXT: store i64 [[BF_SET]], ptr [[C]], align 4 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// BE-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[C]], align 4 +// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BE-NEXT: store i32 [[INC]], ptr [[C]], align 4 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_c_st16( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[C]], align 4 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[C]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LENUMLOADS-NEXT: store i64 [[BF_SET]], ptr [[C]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[C]], align 4 +// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LENUMLOADS-NEXT: store i32 [[INC]], ptr [[C]], align 4 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_c_st16( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[C]], align 4 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[C]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BENUMLOADS-NEXT: store i64 [[BF_SET]], ptr [[C]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[C]], align 4 +// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BENUMLOADS-NEXT: store i32 [[INC]], ptr [[C]], align 4 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_c_st16( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[C]], align 4 -// LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[C]], align 4 -// LEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LEWIDTH-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTH-NEXT: store i64 [[BF_SET]], ptr [[C]], align 4 -// LEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[C]], align 4 +// LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LEWIDTH-NEXT: store i32 [[INC]], ptr [[C]], align 4 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_c_st16( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[C]], align 4 -// BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[C]], align 4 -// BEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BEWIDTH-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTH-NEXT: store i64 [[BF_SET]], ptr [[C]], align 4 -// BEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[C]], align 4 +// BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BEWIDTH-NEXT: store i32 [[INC]], ptr [[C]], align 4 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_c_st16( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[C]], align 4 -// LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[C]], align 4 -// LEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTHNUM-NEXT: store i64 [[BF_SET]], ptr [[C]], align 4 -// LEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[C]], align 4 +// LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LEWIDTHNUM-NEXT: store i32 [[INC]], ptr [[C]], align 4 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_c_st16( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[C]], align 4 -// BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[C]], align 4 -// BEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTHNUM-NEXT: store i64 [[BF_SET]], ptr [[C]], align 4 -// BEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[C]], align 4 +// BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BEWIDTHNUM-NEXT: store i32 [[INC]], ptr [[C]], align 4 // BEWIDTHNUM-NEXT: ret void // void increment_c_st16(struct st16 *s) { @@ -3542,162 +3212,90 @@ void increment_c_st16(struct st16 *s) { // LE-LABEL: @increment_d_st16( // LE-NEXT: entry: -// LE-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LE-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[D]], align 4 -// LE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LE-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// LE-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[D]], align 4 +// LE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LE-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[D]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LE-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LE-NEXT: store i64 [[BF_SET]], ptr [[D]], align 4 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LE-NEXT: store i16 [[TMP0]], ptr [[D]], align 4 +// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LE-NEXT: ret void // // BE-LABEL: @increment_d_st16( // BE-NEXT: entry: -// BE-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BE-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[D]], align 4 -// BE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BE-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// BE-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[D]], align 4 +// BE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BE-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[D]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BE-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BE-NEXT: store i64 [[BF_SET]], ptr [[D]], align 4 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BE-NEXT: store i16 [[TMP0]], ptr [[D]], align 4 +// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_d_st16( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[D]], align 4 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LENUMLOADS-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[D]], align 4 +// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[D]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LENUMLOADS-NEXT: store i64 [[BF_SET]], ptr [[D]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LENUMLOADS-NEXT: store i16 [[TMP0]], ptr [[D]], align 4 +// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_d_st16( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[D]], align 4 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BENUMLOADS-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[D]], align 4 +// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[D]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BENUMLOADS-NEXT: store i64 [[BF_SET]], ptr [[D]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BENUMLOADS-NEXT: store i16 [[TMP0]], ptr [[D]], align 4 +// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_d_st16( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[D]], align 4 -// LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LEWIDTH-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[D]], align 4 +// LEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[D]], align 4 -// LEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LEWIDTH-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LEWIDTH-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LEWIDTH-NEXT: store i64 [[BF_SET]], ptr [[D]], align 4 -// LEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LEWIDTH-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LEWIDTH-NEXT: store i16 [[TMP0]], ptr [[D]], align 4 +// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_d_st16( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[D]], align 4 -// BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BEWIDTH-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[D]], align 4 +// BEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[D]], align 4 -// BEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BEWIDTH-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BEWIDTH-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BEWIDTH-NEXT: store i64 [[BF_SET]], ptr [[D]], align 4 -// BEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BEWIDTH-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BEWIDTH-NEXT: store i16 [[TMP0]], ptr [[D]], align 4 +// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_d_st16( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[D]], align 4 -// LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LEWIDTHNUM-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[D]], align 4 +// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[D]], align 4 -// LEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LEWIDTHNUM-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LEWIDTHNUM-NEXT: store i64 [[BF_SET]], ptr [[D]], align 4 -// LEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LEWIDTHNUM-NEXT: store i16 [[TMP0]], ptr [[D]], align 4 +// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_d_st16( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i64, ptr [[D]], align 4 -// BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BEWIDTHNUM-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[D]], align 4 +// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load i64, ptr [[D]], align 4 -// BEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BEWIDTHNUM-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BEWIDTHNUM-NEXT: store i64 [[BF_SET]], ptr [[D]], align 4 -// BEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BEWIDTHNUM-NEXT: store i16 [[TMP0]], ptr [[D]], align 4 +// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BEWIDTHNUM-NEXT: ret void // void increment_d_st16(struct st16 *s) { @@ -3706,74 +3304,32 @@ void increment_d_st16(struct st16 *s) { // LE-LABEL: @increment_v_a_st16( // LE-NEXT: entry: -// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[S:%.*]], align 4 -// LE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LE-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[S]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LE-NEXT: store volatile i64 [[BF_SET]], ptr [[S]], align 4 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 4 +// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LE-NEXT: store volatile i32 [[INC]], ptr [[S]], align 4 // LE-NEXT: ret void // // BE-LABEL: @increment_v_a_st16( // BE-NEXT: entry: -// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[S:%.*]], align 4 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BE-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[S]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BE-NEXT: store volatile i64 [[BF_SET]], ptr [[S]], align 4 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 4 +// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BE-NEXT: store volatile i32 [[INC]], ptr [[S]], align 4 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_v_a_st16( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[S:%.*]], align 4 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LENUMLOADS-NEXT: store volatile i64 [[BF_SET]], ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 4 +// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[S]], align 4 +// LENUMLOADS-NEXT: store volatile i32 [[INC]], ptr [[S]], align 4 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_v_a_st16( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[S:%.*]], align 4 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BENUMLOADS-NEXT: store volatile i64 [[BF_SET]], ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 4 +// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[S]], align 4 +// BENUMLOADS-NEXT: store volatile i32 [[INC]], ptr [[S]], align 4 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_v_a_st16( @@ -3812,140 +3368,110 @@ void increment_v_a_st16(volatile struct st16 *s) { // LE-LABEL: @increment_v_b_st16( // LE-NEXT: entry: -// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[S:%.*]], align 4 -// LE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LE-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[B]], align 4 +// LE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LE-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[S]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LE-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LE-NEXT: store volatile i64 [[BF_SET]], ptr [[S]], align 4 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LE-NEXT: store volatile i16 [[TMP0]], ptr [[B]], align 4 +// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LE-NEXT: ret void // // BE-LABEL: @increment_v_b_st16( // BE-NEXT: entry: -// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[S:%.*]], align 4 -// BE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BE-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[B]], align 4 +// BE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BE-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[S]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BE-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BE-NEXT: store volatile i64 [[BF_SET]], ptr [[S]], align 4 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BE-NEXT: store volatile i16 [[TMP0]], ptr [[B]], align 4 +// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_v_b_st16( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[S:%.*]], align 4 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LENUMLOADS-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[B]], align 4 +// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LENUMLOADS-NEXT: store volatile i64 [[BF_SET]], ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i16, ptr [[B]], align 4 +// LENUMLOADS-NEXT: store volatile i16 [[TMP0]], ptr [[B]], align 4 +// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_v_b_st16( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[S:%.*]], align 4 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BENUMLOADS-NEXT: [[B:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[B]], align 4 +// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BENUMLOADS-NEXT: store volatile i64 [[BF_SET]], ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i16, ptr [[B]], align 4 +// BENUMLOADS-NEXT: store volatile i16 [[TMP0]], ptr [[B]], align 4 +// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_v_b_st16( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 1 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 1 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 // LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 16 // LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_ASHR]], 1 -// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // LEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i32 [[INC]], 65535 // LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], -65536 // LEWIDTH-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTH-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP1]], align 4 +// LEWIDTH-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP0]], align 4 // LEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // LEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i32 [[BF_RESULT_SHL]], 16 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_v_b_st16( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 1 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 1 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_LOAD]], 16 // BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_ASHR]], 1 -// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // BEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i32 [[INC]], 65535 // BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], 65535 // BEWIDTH-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTH-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP1]], align 4 +// BEWIDTH-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP0]], align 4 // BEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // BEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i32 [[BF_RESULT_SHL]], 16 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_v_b_st16( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 // LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 16 // LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_ASHR]], 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // LEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i32 [[INC]], 65535 // LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], -65536 // LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTHNUM-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP1]], align 4 +// LEWIDTHNUM-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP0]], align 4 // LEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // LEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i32 [[BF_RESULT_SHL]], 16 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_v_b_st16( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_LOAD]], 16 // BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_ASHR]], 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // BEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i32 [[INC]], 65535 // BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], 65535 // BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTHNUM-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP1]], align 4 +// BEWIDTHNUM-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP0]], align 4 // BEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // BEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i32 [[BF_RESULT_SHL]], 16 // BEWIDTHNUM-NEXT: ret void @@ -3956,112 +3482,70 @@ void increment_v_b_st16(volatile struct st16 *s) { // LE-LABEL: @increment_v_c_st16( // LE-NEXT: entry: -// LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[C]], align 4 -// LE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LE-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[C]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LE-NEXT: store volatile i64 [[BF_SET]], ptr [[C]], align 4 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[C]], align 4 +// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LE-NEXT: store volatile i32 [[INC]], ptr [[C]], align 4 // LE-NEXT: ret void // // BE-LABEL: @increment_v_c_st16( // BE-NEXT: entry: -// BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[C]], align 4 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BE-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[C]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BE-NEXT: store volatile i64 [[BF_SET]], ptr [[C]], align 4 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[C]], align 4 +// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BE-NEXT: store volatile i32 [[INC]], ptr [[C]], align 4 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_v_c_st16( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[C]], align 4 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 32 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[C]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294967296 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_VALUE]] -// LENUMLOADS-NEXT: store volatile i64 [[BF_SET]], ptr [[C]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[C]], align 4 +// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[C]], align 4 +// LENUMLOADS-NEXT: store volatile i32 [[INC]], ptr [[C]], align 4 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_v_c_st16( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[C]], align 4 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_LOAD]], 32 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 -// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[C]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL]] -// BENUMLOADS-NEXT: store volatile i64 [[BF_SET]], ptr [[C]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[C]], align 4 +// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[C]], align 4 +// BENUMLOADS-NEXT: store volatile i32 [[INC]], ptr [[C]], align 4 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_v_c_st16( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 2 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[C]], align 4 // LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 -// LEWIDTH-NEXT: store volatile i32 [[INC]], ptr [[TMP1]], align 4 +// LEWIDTH-NEXT: store volatile i32 [[INC]], ptr [[C]], align 4 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_v_c_st16( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 2 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[C]], align 4 // BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 -// BEWIDTH-NEXT: store volatile i32 [[INC]], ptr [[TMP1]], align 4 +// BEWIDTH-NEXT: store volatile i32 [[INC]], ptr [[C]], align 4 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_v_c_st16( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 2 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[C]], align 4 // LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 -// LEWIDTHNUM-NEXT: store volatile i32 [[INC]], ptr [[TMP1]], align 4 +// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[C]], align 4 +// LEWIDTHNUM-NEXT: store volatile i32 [[INC]], ptr [[C]], align 4 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_v_c_st16( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 2 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 2 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[C]], align 4 // BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 -// BEWIDTHNUM-NEXT: store volatile i32 [[INC]], ptr [[TMP1]], align 4 +// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[C]], align 4 +// BEWIDTHNUM-NEXT: store volatile i32 [[INC]], ptr [[C]], align 4 // BEWIDTHNUM-NEXT: ret void // void increment_v_c_st16(volatile struct st16 *s) { @@ -4070,144 +3554,110 @@ void increment_v_c_st16(volatile struct st16 *s) { // LE-LABEL: @increment_v_d_st16( // LE-NEXT: entry: -// LE-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[D]], align 4 -// LE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LE-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[D]], align 4 +// LE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LE-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[D]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LE-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LE-NEXT: store volatile i64 [[BF_SET]], ptr [[D]], align 4 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LE-NEXT: store volatile i16 [[TMP0]], ptr [[D]], align 4 +// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LE-NEXT: ret void // // BE-LABEL: @increment_v_d_st16( // BE-NEXT: entry: -// BE-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[D]], align 4 -// BE-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BE-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[D]], align 4 +// BE-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BE-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[D]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BE-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BE-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BE-NEXT: store volatile i64 [[BF_SET]], ptr [[D]], align 4 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BE-NEXT: store volatile i16 [[TMP0]], ptr [[D]], align 4 +// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_v_d_st16( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[D]], align 4 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 16 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// LENUMLOADS-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[D]], align 4 +// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[D]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// LENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -281470681743361 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// LENUMLOADS-NEXT: store volatile i64 [[BF_SET]], ptr [[D]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i16, ptr [[D]], align 4 +// LENUMLOADS-NEXT: store volatile i16 [[TMP0]], ptr [[D]], align 4 +// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_v_d_st16( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 1 -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i64, ptr [[D]], align 4 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i64 [[BF_LOAD]], 32 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i64 [[BF_SHL]], 48 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i64 [[BF_ASHR]] to i32 +// BENUMLOADS-NEXT: [[D:%.*]] = getelementptr inbounds [[STRUCT_ST16:%.*]], ptr [[S:%.*]], i32 0, i32 3 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[D]], align 4 +// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i16 [[BF_LOAD]] to i32 // BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i64 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i64, ptr [[D]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i64 [[TMP1]], 65535 -// BENUMLOADS-NEXT: [[BF_SHL2:%.*]] = shl i64 [[BF_VALUE]], 16 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i64 [[BF_LOAD1]], -4294901761 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i64 [[BF_CLEAR]], [[BF_SHL2]] -// BENUMLOADS-NEXT: store volatile i64 [[BF_SET]], ptr [[D]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i64 [[BF_VALUE]], 48 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i64 [[BF_RESULT_SHL]], 48 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i64 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i16 +// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i16, ptr [[D]], align 4 +// BENUMLOADS-NEXT: store volatile i16 [[TMP0]], ptr [[D]], align 4 +// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i16 [[TMP0]] to i32 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_v_d_st16( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 3 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 3 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 // LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 16 // LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_ASHR]], 1 -// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // LEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i32 [[INC]], 65535 // LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], -65536 // LEWIDTH-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTH-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP1]], align 4 +// LEWIDTH-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP0]], align 4 // LEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // LEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i32 [[BF_RESULT_SHL]], 16 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_v_d_st16( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 3 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 3 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_LOAD]], 16 // BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_ASHR]], 1 -// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // BEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i32 [[INC]], 65535 // BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], 65535 // BEWIDTH-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTH-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP1]], align 4 +// BEWIDTH-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP0]], align 4 // BEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // BEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i32 [[BF_RESULT_SHL]], 16 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_v_d_st16( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 3 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 3 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_LOAD]], 16 // LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_SHL]], 16 // LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_ASHR]], 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // LEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i32 [[INC]], 65535 // LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], -65536 // LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTHNUM-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP1]], align 4 +// LEWIDTHNUM-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP0]], align 4 // LEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // LEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i32 [[BF_RESULT_SHL]], 16 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_v_d_st16( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 3 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[S:%.*]], i32 3 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i32 [[BF_LOAD]], 16 // BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_ASHR]], 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP1]], align 4 +// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[TMP0]], align 4 // BEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i32 [[INC]], 65535 // BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD1]], 65535 // BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i32 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTHNUM-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP1]], align 4 +// BEWIDTHNUM-NEXT: store volatile i32 [[BF_SET]], ptr [[TMP0]], align 4 // BEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i32 [[BF_VALUE]], 16 // BEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i32 [[BF_RESULT_SHL]], 16 // BEWIDTHNUM-NEXT: ret void @@ -4224,146 +3674,62 @@ char c : 8; // LE-LABEL: @increment_v_b_st17( // LE-NEXT: entry: -// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LE-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 8 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 8 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// LE-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LE-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296 -// LE-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// LE-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 1 +// LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LE-NEXT: store volatile i32 [[INC]], ptr [[S]], align 1 // LE-NEXT: ret void // // BE-LABEL: @increment_v_b_st17( // BE-NEXT: entry: -// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 8 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// BE-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BE-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// BE-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255 -// BE-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// BE-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 1 +// BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BE-NEXT: store volatile i32 [[INC]], ptr [[S]], align 1 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_v_b_st17( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 8 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 8 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// LENUMLOADS-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 1 +// LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[S]], align 1 +// LENUMLOADS-NEXT: store volatile i32 [[INC]], ptr [[S]], align 1 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_v_b_st17( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 8 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// BENUMLOADS-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 1 +// BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[S]], align 1 +// BENUMLOADS-NEXT: store volatile i32 [[INC]], ptr [[S]], align 1 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_v_b_st17( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 8 -// LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 8 -// LEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// LEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296 -// LEWIDTH-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTH-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 1 +// LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LEWIDTH-NEXT: store volatile i32 [[INC]], ptr [[S]], align 1 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_v_b_st17( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 8 -// BEWIDTH-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTH-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BEWIDTH-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// BEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BEWIDTH-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255 -// BEWIDTH-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTH-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BEWIDTH-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BEWIDTH-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 1 +// BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BEWIDTH-NEXT: store volatile i32 [[INC]], ptr [[S]], align 1 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_v_b_st17( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 8 -// LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 8 -// LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// LEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -4294967296 -// LEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// LEWIDTHNUM-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// LEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 1 +// LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[S]], align 1 +// LEWIDTHNUM-NEXT: store volatile i32 [[INC]], ptr [[S]], align 1 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_v_b_st17( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 8 -// BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i32 -// BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = zext i32 [[INC]] to i40 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BEWIDTHNUM-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 4294967295 -// BEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BEWIDTHNUM-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 255 -// BEWIDTHNUM-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// BEWIDTHNUM-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BEWIDTHNUM-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 8 -// BEWIDTHNUM-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 8 -// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i32 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i32, ptr [[S:%.*]], align 1 +// BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_LOAD]], 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i32, ptr [[S]], align 1 +// BEWIDTHNUM-NEXT: store volatile i32 [[INC]], ptr [[S]], align 1 // BEWIDTHNUM-NEXT: ret void // void increment_v_b_st17(volatile struct st17 *s) { @@ -4372,108 +3738,70 @@ void increment_v_b_st17(volatile struct st17 *s) { // LE-LABEL: @increment_v_c_st17( // LE-NEXT: entry: -// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LE-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 32 -// LE-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i8 -// LE-NEXT: [[INC:%.*]] = add i8 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = zext i8 [[INC]] to i40 -// LE-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LE-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 255 -// LE-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 4294967295 -// LE-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// LE-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 32 -// LE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 32 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i8 +// LE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST17:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 1 +// LE-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 +// LE-NEXT: store volatile i8 [[INC]], ptr [[C]], align 1 // LE-NEXT: ret void // // BE-LABEL: @increment_v_c_st17( // BE-NEXT: entry: -// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BE-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 32 -// BE-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 32 -// BE-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i8 -// BE-NEXT: [[INC:%.*]] = add i8 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = zext i8 [[INC]] to i40 -// BE-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BE-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 255 -// BE-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -256 -// BE-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// BE-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BE-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 32 -// BE-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 32 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i8 +// BE-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST17:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 1 +// BE-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 +// BE-NEXT: store volatile i8 [[INC]], ptr [[C]], align 1 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_v_c_st17( // LENUMLOADS-NEXT: entry: -// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// LENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_LOAD]], 32 -// LENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i8 -// LENUMLOADS-NEXT: [[INC:%.*]] = add i8 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = zext i8 [[INC]] to i40 -// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 255 -// LENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], 4294967295 -// LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_SHL]] -// LENUMLOADS-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// LENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 32 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i8 +// LENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST17:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 1 +// LENUMLOADS-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 +// LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 +// LENUMLOADS-NEXT: store volatile i8 [[INC]], ptr [[C]], align 1 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_v_c_st17( // BENUMLOADS-NEXT: entry: -// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i40, ptr [[S:%.*]], align 1 -// BENUMLOADS-NEXT: [[BF_SHL:%.*]] = shl i40 [[BF_LOAD]], 32 -// BENUMLOADS-NEXT: [[BF_ASHR:%.*]] = ashr i40 [[BF_SHL]], 32 -// BENUMLOADS-NEXT: [[BF_CAST:%.*]] = trunc i40 [[BF_ASHR]] to i8 -// BENUMLOADS-NEXT: [[INC:%.*]] = add i8 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = zext i8 [[INC]] to i40 -// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i40, ptr [[S]], align 1 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i40 [[TMP1]], 255 -// BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i40 [[BF_LOAD1]], -256 -// BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i40 [[BF_CLEAR]], [[BF_VALUE]] -// BENUMLOADS-NEXT: store volatile i40 [[BF_SET]], ptr [[S]], align 1 -// BENUMLOADS-NEXT: [[BF_RESULT_SHL:%.*]] = shl i40 [[BF_VALUE]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_ASHR:%.*]] = ashr i40 [[BF_RESULT_SHL]], 32 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = trunc i40 [[BF_RESULT_ASHR]] to i8 +// BENUMLOADS-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST17:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 1 +// BENUMLOADS-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 +// BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 +// BENUMLOADS-NEXT: store volatile i8 [[INC]], ptr [[C]], align 1 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_v_c_st17( // LEWIDTH-NEXT: entry: -// LEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i32 4 -// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// LEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST17:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 1 // LEWIDTH-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 -// LEWIDTH-NEXT: store volatile i8 [[INC]], ptr [[TMP1]], align 1 +// LEWIDTH-NEXT: store volatile i8 [[INC]], ptr [[C]], align 1 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_v_c_st17( // BEWIDTH-NEXT: entry: -// BEWIDTH-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i32 4 -// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// BEWIDTH-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST17:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 1 // BEWIDTH-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 -// BEWIDTH-NEXT: store volatile i8 [[INC]], ptr [[TMP1]], align 1 +// BEWIDTH-NEXT: store volatile i8 [[INC]], ptr [[C]], align 1 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_v_c_st17( // LEWIDTHNUM-NEXT: entry: -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i32 4 -// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// LEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST17:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 1 // LEWIDTHNUM-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP1]], align 1 -// LEWIDTHNUM-NEXT: store volatile i8 [[INC]], ptr [[TMP1]], align 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 +// LEWIDTHNUM-NEXT: store volatile i8 [[INC]], ptr [[C]], align 1 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_v_c_st17( // BEWIDTHNUM-NEXT: entry: -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[S:%.*]], i32 4 -// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[TMP1]], align 1 +// BEWIDTHNUM-NEXT: [[C:%.*]] = getelementptr inbounds [[STRUCT_ST17:%.*]], ptr [[S:%.*]], i32 0, i32 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[C]], align 1 // BEWIDTHNUM-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP1]], align 1 -// BEWIDTHNUM-NEXT: store volatile i8 [[INC]], ptr [[TMP1]], align 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[C]], align 1 +// BEWIDTHNUM-NEXT: store volatile i8 [[INC]], ptr [[C]], align 1 // BEWIDTHNUM-NEXT: ret void // void increment_v_c_st17(volatile struct st17 *s) { @@ -4493,9 +3821,9 @@ struct zero_bitfield { // LE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 4 // LE-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // LE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LE-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 -// LE-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 4 -// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// LE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 +// LE-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 4 +// LE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // LE-NEXT: ret void // // BE-LABEL: @increment_a_zero_bitfield( @@ -4503,9 +3831,9 @@ struct zero_bitfield { // BE-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 4 // BE-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // BE-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BE-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 -// BE-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 4 -// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// BE-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 +// BE-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 4 +// BE-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // BE-NEXT: ret void // // LENUMLOADS-LABEL: @increment_a_zero_bitfield( @@ -4513,10 +3841,10 @@ struct zero_bitfield { // LENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 4 // LENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // LENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LENUMLOADS-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 // LENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[S]], align 4 -// LENUMLOADS-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// LENUMLOADS-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 4 +// LENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // LENUMLOADS-NEXT: ret void // // BENUMLOADS-LABEL: @increment_a_zero_bitfield( @@ -4524,10 +3852,10 @@ struct zero_bitfield { // BENUMLOADS-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 4 // BENUMLOADS-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // BENUMLOADS-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BENUMLOADS-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 // BENUMLOADS-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[S]], align 4 -// BENUMLOADS-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// BENUMLOADS-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 4 +// BENUMLOADS-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // BENUMLOADS-NEXT: ret void // // LEWIDTH-LABEL: @increment_a_zero_bitfield( @@ -4535,9 +3863,9 @@ struct zero_bitfield { // LEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 4 // LEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // LEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTH-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 -// LEWIDTH-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 4 -// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// LEWIDTH-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 +// LEWIDTH-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 4 +// LEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_a_zero_bitfield( @@ -4545,9 +3873,9 @@ struct zero_bitfield { // BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 4 // BEWIDTH-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // BEWIDTH-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTH-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 -// BEWIDTH-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 4 -// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// BEWIDTH-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 +// BEWIDTH-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 4 +// BEWIDTH-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_a_zero_bitfield( @@ -4555,10 +3883,10 @@ struct zero_bitfield { // LEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 4 // LEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // LEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// LEWIDTHNUM-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 // LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[S]], align 4 -// LEWIDTHNUM-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 4 -// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// LEWIDTHNUM-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 4 +// LEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_a_zero_bitfield( @@ -4566,10 +3894,10 @@ struct zero_bitfield { // BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i8, ptr [[S:%.*]], align 4 // BEWIDTHNUM-NEXT: [[BF_CAST:%.*]] = sext i8 [[BF_LOAD]] to i32 // BEWIDTHNUM-NEXT: [[INC:%.*]] = add nsw i32 [[BF_CAST]], 1 -// BEWIDTHNUM-NEXT: [[TMP1:%.*]] = trunc i32 [[INC]] to i8 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = trunc i32 [[INC]] to i8 // BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[S]], align 4 -// BEWIDTHNUM-NEXT: store volatile i8 [[TMP1]], ptr [[S]], align 4 -// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP1]] to i32 +// BEWIDTHNUM-NEXT: store volatile i8 [[TMP0]], ptr [[S]], align 4 +// BEWIDTHNUM-NEXT: [[BF_RESULT_CAST:%.*]] = sext i8 [[TMP0]] to i32 // BEWIDTHNUM-NEXT: ret void // void increment_a_zero_bitfield(volatile struct zero_bitfield *s) { @@ -4692,9 +4020,9 @@ struct zero_bitfield_ok { // LE-NEXT: [[CONV3:%.*]] = sext i8 [[BF_CAST]] to i32 // LE-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV3]], [[CONV]] // LE-NEXT: [[CONV4:%.*]] = trunc i32 [[ADD]] to i8 -// LE-NEXT: [[TMP2:%.*]] = zext i8 [[CONV4]] to i16 +// LE-NEXT: [[TMP0:%.*]] = zext i8 [[CONV4]] to i16 // LE-NEXT: [[BF_LOAD5:%.*]] = load volatile i16, ptr [[S]], align 4 -// LE-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP2]], 255 +// LE-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP0]], 255 // LE-NEXT: [[BF_SHL6:%.*]] = shl i16 [[BF_VALUE]], 8 // LE-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD5]], 255 // LE-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_SHL6]] @@ -4716,9 +4044,9 @@ struct zero_bitfield_ok { // BE-NEXT: [[CONV3:%.*]] = sext i8 [[BF_CAST]] to i32 // BE-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV3]], [[CONV]] // BE-NEXT: [[CONV4:%.*]] = trunc i32 [[ADD]] to i8 -// BE-NEXT: [[TMP2:%.*]] = zext i8 [[CONV4]] to i16 +// BE-NEXT: [[TMP0:%.*]] = zext i8 [[CONV4]] to i16 // BE-NEXT: [[BF_LOAD5:%.*]] = load volatile i16, ptr [[S]], align 4 -// BE-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP2]], 255 +// BE-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP0]], 255 // BE-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD5]], -256 // BE-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_VALUE]] // BE-NEXT: store volatile i16 [[BF_SET]], ptr [[S]], align 4 @@ -4739,9 +4067,9 @@ struct zero_bitfield_ok { // LENUMLOADS-NEXT: [[CONV3:%.*]] = sext i8 [[BF_CAST]] to i32 // LENUMLOADS-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV3]], [[CONV]] // LENUMLOADS-NEXT: [[CONV4:%.*]] = trunc i32 [[ADD]] to i8 -// LENUMLOADS-NEXT: [[TMP2:%.*]] = zext i8 [[CONV4]] to i16 +// LENUMLOADS-NEXT: [[TMP0:%.*]] = zext i8 [[CONV4]] to i16 // LENUMLOADS-NEXT: [[BF_LOAD5:%.*]] = load volatile i16, ptr [[S]], align 4 -// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP2]], 255 +// LENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP0]], 255 // LENUMLOADS-NEXT: [[BF_SHL6:%.*]] = shl i16 [[BF_VALUE]], 8 // LENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD5]], 255 // LENUMLOADS-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_SHL6]] @@ -4763,9 +4091,9 @@ struct zero_bitfield_ok { // BENUMLOADS-NEXT: [[CONV3:%.*]] = sext i8 [[BF_CAST]] to i32 // BENUMLOADS-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV3]], [[CONV]] // BENUMLOADS-NEXT: [[CONV4:%.*]] = trunc i32 [[ADD]] to i8 -// BENUMLOADS-NEXT: [[TMP2:%.*]] = zext i8 [[CONV4]] to i16 +// BENUMLOADS-NEXT: [[TMP0:%.*]] = zext i8 [[CONV4]] to i16 // BENUMLOADS-NEXT: [[BF_LOAD5:%.*]] = load volatile i16, ptr [[S]], align 4 -// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP2]], 255 +// BENUMLOADS-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP0]], 255 // BENUMLOADS-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD5]], -256 // BENUMLOADS-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_VALUE]] // BENUMLOADS-NEXT: store volatile i16 [[BF_SET]], ptr [[S]], align 4 @@ -4780,12 +4108,12 @@ struct zero_bitfield_ok { // LEWIDTH-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 8 // LEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8 // LEWIDTH-NEXT: [[CONV:%.*]] = sext i16 [[BF_ASHR]] to i32 -// LEWIDTH-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 1 -// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP2]], align 1 +// LEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 1 +// LEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // LEWIDTH-NEXT: [[CONV2:%.*]] = sext i8 [[BF_LOAD1]] to i32 // LEWIDTH-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV2]], [[CONV]] // LEWIDTH-NEXT: [[CONV3:%.*]] = trunc i32 [[ADD]] to i8 -// LEWIDTH-NEXT: store volatile i8 [[CONV3]], ptr [[TMP2]], align 1 +// LEWIDTH-NEXT: store volatile i8 [[CONV3]], ptr [[TMP0]], align 1 // LEWIDTH-NEXT: ret void // // BEWIDTH-LABEL: @increment_a_zero_bitfield_ok( @@ -4793,12 +4121,12 @@ struct zero_bitfield_ok { // BEWIDTH-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[S:%.*]], align 4 // BEWIDTH-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_LOAD]], 8 // BEWIDTH-NEXT: [[CONV:%.*]] = sext i16 [[BF_ASHR]] to i32 -// BEWIDTH-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 1 -// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP2]], align 1 +// BEWIDTH-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 1 +// BEWIDTH-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // BEWIDTH-NEXT: [[CONV2:%.*]] = sext i8 [[BF_LOAD1]] to i32 // BEWIDTH-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV2]], [[CONV]] // BEWIDTH-NEXT: [[CONV3:%.*]] = trunc i32 [[ADD]] to i8 -// BEWIDTH-NEXT: store volatile i8 [[CONV3]], ptr [[TMP2]], align 1 +// BEWIDTH-NEXT: store volatile i8 [[CONV3]], ptr [[TMP0]], align 1 // BEWIDTH-NEXT: ret void // // LEWIDTHNUM-LABEL: @increment_a_zero_bitfield_ok( @@ -4807,13 +4135,13 @@ struct zero_bitfield_ok { // LEWIDTHNUM-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 8 // LEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_SHL]], 8 // LEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i16 [[BF_ASHR]] to i32 -// LEWIDTHNUM-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 1 -// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP2]], align 1 +// LEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // LEWIDTHNUM-NEXT: [[CONV2:%.*]] = sext i8 [[BF_LOAD1]] to i32 // LEWIDTHNUM-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV2]], [[CONV]] // LEWIDTHNUM-NEXT: [[CONV3:%.*]] = trunc i32 [[ADD]] to i8 -// LEWIDTHNUM-NEXT: [[BF_LOAD4:%.*]] = load volatile i8, ptr [[TMP2]], align 1 -// LEWIDTHNUM-NEXT: store volatile i8 [[CONV3]], ptr [[TMP2]], align 1 +// LEWIDTHNUM-NEXT: [[BF_LOAD4:%.*]] = load volatile i8, ptr [[TMP0]], align 1 +// LEWIDTHNUM-NEXT: store volatile i8 [[CONV3]], ptr [[TMP0]], align 1 // LEWIDTHNUM-NEXT: ret void // // BEWIDTHNUM-LABEL: @increment_a_zero_bitfield_ok( @@ -4821,13 +4149,13 @@ struct zero_bitfield_ok { // BEWIDTHNUM-NEXT: [[BF_LOAD:%.*]] = load volatile i16, ptr [[S:%.*]], align 4 // BEWIDTHNUM-NEXT: [[BF_ASHR:%.*]] = ashr i16 [[BF_LOAD]], 8 // BEWIDTHNUM-NEXT: [[CONV:%.*]] = sext i16 [[BF_ASHR]] to i32 -// BEWIDTHNUM-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 1 -// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP2]], align 1 +// BEWIDTHNUM-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD1:%.*]] = load volatile i8, ptr [[TMP0]], align 1 // BEWIDTHNUM-NEXT: [[CONV2:%.*]] = sext i8 [[BF_LOAD1]] to i32 // BEWIDTHNUM-NEXT: [[ADD:%.*]] = add nsw i32 [[CONV2]], [[CONV]] // BEWIDTHNUM-NEXT: [[CONV3:%.*]] = trunc i32 [[ADD]] to i8 -// BEWIDTHNUM-NEXT: [[BF_LOAD4:%.*]] = load volatile i8, ptr [[TMP2]], align 1 -// BEWIDTHNUM-NEXT: store volatile i8 [[CONV3]], ptr [[TMP2]], align 1 +// BEWIDTHNUM-NEXT: [[BF_LOAD4:%.*]] = load volatile i8, ptr [[TMP0]], align 1 +// BEWIDTHNUM-NEXT: store volatile i8 [[CONV3]], ptr [[TMP0]], align 1 // BEWIDTHNUM-NEXT: ret void // void increment_a_zero_bitfield_ok(volatile struct zero_bitfield_ok *s) { diff --git a/clang/test/CodeGen/arm-bitfield-alignment.c b/clang/test/CodeGen/arm-bitfield-alignment.c index e34789face5584..5d0967ec70346c 100644 --- a/clang/test/CodeGen/arm-bitfield-alignment.c +++ b/clang/test/CodeGen/arm-bitfield-alignment.c @@ -1,5 +1,7 @@ -// RUN: %clang_cc1 -triple arm-none-eabi -ffreestanding -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple aarch64 -ffreestanding -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm-none-eabi -fdump-record-layouts-simple -ffreestanding -emit-llvm -o %t %s | FileCheck %s -check-prefixes=LAYOUT,LAYOUT-32 +// RUN: FileCheck %s -check-prefixes=IR,IR-32 <%t +// RUN: %clang_cc1 -triple aarch64 -fdump-record-layouts-simple -ffreestanding -emit-llvm -o %t %s | FileCheck %s -check-prefixes=LAYOUT,LAYOUT-64 +// RUN: FileCheck %s -check-prefixes=IR,IR-64 <%t extern struct T { int b0 : 8; @@ -11,5 +13,18 @@ int func(void) { return g.b1; } -// CHECK: @g = external global %struct.T, align 4 -// CHECK: %{{.*}} = load i64, ptr @g, align 4 +// IR: @g = external global %struct.T, align 4 +// IR-32: %{{.*}} = load i32, ptr @g, align 4 +// IR-64: %{{.*}} = load i64, ptr @g, align 4 + +// LAYOUT-LABEL: LLVMType:%struct.T = +// LAYOUT-32-SAME: type { i32, i8 } +// LAYOUT-64-SAME: type { i64 } +// LAYOUT: BitFields:[ +// LAYOUT-32-NEXT: diff --git a/clang/test/CodeGen/arm64-be-bitfield.c b/clang/test/CodeGen/arm64-be-bitfield.c index 58c31853929847..57e20b5b62b9ca 100644 --- a/clang/test/CodeGen/arm64-be-bitfield.c +++ b/clang/test/CodeGen/arm64-be-bitfield.c @@ -1,11 +1,25 @@ -// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - %s | FileCheck --check-prefix IR %s +// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o %t -fdump-record-layouts-simple %s | FileCheck %s --check-prefix=LAYOUT +// RUN: FileCheck %s --check-prefix=IR <%t struct bt3 { signed b2:10; signed b3:10; } b16; // Get the high 32-bits and then shift appropriately for big-endian. signed callee_b0f(struct bt3 bp11) { // IR: callee_b0f(i64 [[ARG:%.*]]) -// IR: store i64 [[ARG]], ptr [[PTR:%.*]], align 8 -// IR: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}, ptr align 8 [[PTR]], i64 4 +// IR: [[BP11:%.*]] = alloca %struct.bt3, align 4 +// IR: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.bt3, ptr [[BP11]], i32 0, i32 0 +// IR: [[COERCE_HIGHBITS:%.*]] = lshr i64 [[ARG]], 32 +// IR: [[COERCE_VAL_II:%.*]] = trunc i64 [[COERCE_HIGHBITS]] to i32 +// IR: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4 +// IR: [[BF_LOAD:%.*]] = load i32, ptr [[BP11]], align 4 +// IR: [[BF_ASHR:%.*]] = ashr i32 [[BF_LOAD]], 22 +// IR: ret i32 [[BF_ASHR]] return bp11.b2; } + +// LAYOUT-LABEL: LLVMType:%struct.bt3 = +// LAYOUT-SAME: type { i32 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: diff --git a/clang/test/CodeGen/atomic.c b/clang/test/CodeGen/atomic.c index af5c056bbfe6e8..16c29e282ddd9f 100644 --- a/clang/test/CodeGen/atomic.c +++ b/clang/test/CodeGen/atomic.c @@ -1,10 +1,14 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-apple-darwin9 | FileCheck %s --check-prefixes=CHECK,X86 +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=s390x-linux-gnu | FileCheck %s --check-prefixes=CHECK,SYSTEMZ // CHECK: @[[NONSTATIC_GLOB_POINTER_FROM_INT:.+]] = global ptr null // CHECK: @[[GLOB_POINTER:.+]] = internal global ptr null // CHECK: @[[GLOB_POINTER_FROM_INT:.+]] = internal global ptr null // CHECK: @[[GLOB_INT:.+]] = internal global i32 0 // CHECK: @[[GLOB_FLT:.+]] = internal global float {{[0e\+-\.]+}}, align +// CHECK: @[[GLOB_DBL:.+]] = internal global double {{[0e\+-\.]+}}, align +// X86: @[[GLOB_LONGDBL:.+]] = internal global x86_fp80 {{[0xK]+}}, align +// SYSTEMZ: @[[GLOB_LONGDBL:.+]] = internal global fp128 {{[0xL]+}}, align int atomic(void) { // non-sensical test for sync functions @@ -79,8 +83,10 @@ int atomic(void) { // CHECK: atomicrmw nand ptr %valc, i8 6 seq_cst, align 1 __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0); - // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg ptr null, i32 0, i32 0 seq_cst seq_cst, align 4 - // CHECK: extractvalue { i32, i1 } [[PAIR]], 0 + // X86: [[PAIR:%[a-z0-9_.]+]] = cmpxchg ptr null, i32 0, i32 0 seq_cst seq_cst, align 4 + // X86-NEXT: extractvalue { i32, i1 } [[PAIR]], 0 + // SYSTEMZ: [[PAIR:%[a-z0-9_.]+]] = cmpxchg ptr null, i64 0, i64 0 seq_cst seq_cst, align 8 + // SYSTEMZ-NEXT: extractvalue { i64, i1 } [[PAIR]], 0 if ( __sync_val_compare_and_swap(&valb, 0, 1)) { // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg ptr %valb, i8 0, i8 1 seq_cst seq_cst, align 1 @@ -90,13 +96,15 @@ int atomic(void) { } __sync_bool_compare_and_swap((void **)0, (void *)0, (void *)0); - // CHECK: cmpxchg ptr null, i32 0, i32 0 seq_cst seq_cst, align 4 + // X86: cmpxchg ptr null, i32 0, i32 0 seq_cst seq_cst, align 4 + // SYSTEMZ: cmpxchg ptr null, i64 0, i64 0 seq_cst seq_cst, align 8 __sync_lock_release(&val); // CHECK: store atomic i32 0, {{.*}} release, align 4 __sync_lock_release(&ptrval); - // CHECK: store atomic i32 0, {{.*}} release, align 4 + // X86: store atomic i32 0, {{.*}} release, align 4 + // SYSTEMZ: store atomic i64 0, {{.*}} release, align 8 __sync_synchronize (); // CHECK: fence seq_cst @@ -131,19 +139,25 @@ static _Atomic(int *) glob_pointer_from_int = 0; _Atomic(int *) nonstatic_glob_pointer_from_int = 0LL; static _Atomic int glob_int = 0; static _Atomic float glob_flt = 0.0f; +static _Atomic double glob_dbl = 0.0f; +static _Atomic long double glob_longdbl = 0.0f; void force_global_uses(void) { + // X86: %atomic-temp = alloca x86_fp80, align 16 (void)glob_pointer; - // CHECK: %[[LOCAL_INT:.+]] = load atomic i32, ptr @[[GLOB_POINTER]] seq_cst - // CHECK-NEXT: inttoptr i32 %[[LOCAL_INT]] to ptr + // CHECK: load atomic ptr, ptr @[[GLOB_POINTER]] seq_cst (void)glob_pointer_from_int; - // CHECK: %[[LOCAL_INT_2:.+]] = load atomic i32, ptr @[[GLOB_POINTER_FROM_INT]] seq_cst - // CHECK-NEXT: inttoptr i32 %[[LOCAL_INT_2]] to ptr + // CHECK-NEXT: load atomic ptr, ptr @[[GLOB_POINTER_FROM_INT]] seq_cst (void)nonstatic_glob_pointer_from_int; - // CHECK: %[[LOCAL_INT_3:.+]] = load atomic i32, ptr @[[NONSTATIC_GLOB_POINTER_FROM_INT]] seq_cst - // CHECK-NEXT: inttoptr i32 %[[LOCAL_INT_3]] to ptr + // CHECK-NEXT: load atomic ptr, ptr @[[NONSTATIC_GLOB_POINTER_FROM_INT]] seq_cst (void)glob_int; - // CHECK: load atomic i32, ptr @[[GLOB_INT]] seq_cst + // CHECK-NEXT: load atomic i32, ptr @[[GLOB_INT]] seq_cst (void)glob_flt; - // CHECK: load atomic float, ptr @[[GLOB_FLT]] seq_cst + // CHECK-NEXT: load atomic float, ptr @[[GLOB_FLT]] seq_cst + (void)glob_dbl; + // CHECK-NEXT: load atomic double, ptr @[[GLOB_DBL]] seq_cst + (void)glob_longdbl; + // X86: call void @__atomic_load(i32 noundef 16, ptr noundef @glob_longdbl, ptr noundef %atomic-temp + // X86-NEXT: %0 = load x86_fp80, ptr %atomic-temp, align 16 + // SYSTEMZ: load atomic fp128, ptr @[[GLOB_LONGDBL]] seq_cst } diff --git a/clang/test/CodeGen/bitfield-2.c b/clang/test/CodeGen/bitfield-2.c index 3e0b30c7a17d80..8688ba6390ddbe 100644 --- a/clang/test/CodeGen/bitfield-2.c +++ b/clang/test/CodeGen/bitfield-2.c @@ -271,11 +271,11 @@ _Bool test_6(void) { // CHECK-RECORD: *** Dumping IRgen Record Layout // CHECK-RECORD: Record: RecordDecl{{.*}}s7 // CHECK-RECORD: Layout: // CHECK-RECORD: IsZeroInitializable:1 // CHECK-RECORD: BitFields:[ -// CHECK-RECORD: + +// This will often be align(1) with -fno-bitfield-type-align +struct P2 { + unsigned a :8; + char :0; + short :0; + unsigned b :8; +} p2; +// CHECK-LABEL: LLVMType:%struct.P2 = +// LAYOUT-T-SAME: type { i8, i8, i8, i8 } +// LAYOUT-ARM64-T-SAME: type { i8, i8, i8, i8 } +// LAYOUT-NT-SAME: type { i8, i8 } +// LAYOUT-STRICT-NT-SAME: type { i8, i8 } +// LAYOUT-DWN32-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +struct P3 { + unsigned a :8; + char :0; + short :0; + unsigned :0; + unsigned b :8; +} p3; +// CHECK-LABEL: LLVMType:%struct.P3 = +// LAYOUT-T-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// LAYOUT-ARM64-T-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// LAYOUT-NT-SAME: type { i8, i8 } +// LAYOUT-STRICT-NT-SAME: type { i8, i8 } +// LAYOUT-DWN32-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +struct P4 { + unsigned a :8; + short :0; + unsigned :0; + unsigned b :8; +} p4; +// CHECK-LABEL: LLVMType:%struct.P4 = +// LAYOUT-T-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// LAYOUT-ARM64-T-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// LAYOUT-NT-SAME: type { i8, i8 } +// LAYOUT-STRICT-NT-SAME: type { i8, i8 } +// LAYOUT-DWN32-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +struct P5 { + unsigned a :8; + unsigned :0; + unsigned b :8; +} p5; +// CHECK-LABEL: LLVMType:%struct.P5 = +// LAYOUT-T-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// LAYOUT-ARM64-T-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// LAYOUT-NT-SAME: type { i8, i8 } +// LAYOUT-STRICT-NT-SAME: type { i8, i8 } +// LAYOUT-DWN32-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +struct P6 { + unsigned a :8; + unsigned :0; + short :0; + char :0; + unsigned b :8; +} p6; +// CHECK-LABEL: LLVMType:%struct.P6 = +// LAYOUT-T-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// LAYOUT-ARM64-T-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// LAYOUT-NT-SAME: type { i8, i8 } +// LAYOUT-STRICT-NT-SAME: type { i8, i8 } +// LAYOUT-DWN32-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +struct P7 { + unsigned a : 8; + short : 0; + unsigned char b : 8; +} p7; +// CHECK-LABEL: LLVMType:%struct.P7 = +// LAYOUT-T-SAME: type { i8, i8, i8, i8 } +// LAYOUT-ARM64-T-SAME: type { i8, i8, i8, i8 } +// LAYOUT-NT-SAME: type { i8, i8 } +// LAYOUT-STRICT-NT-SAME: type { i8, i8 } +// LAYOUT-DWN32-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +// And with forced alignment for !useZeroLengthBitfieldAlignment machines (eg +// hexagon) +struct __attribute__ ((aligned (2))) P7_align { + unsigned a : 8; + short : 0; + unsigned char b : 8; +} p7_align; +// CHECK-LABEL: LLVMType:%struct.P7_align = +// LAYOUT-T-SAME: type { i8, i8, i8, i8 } +// LAYOUT-ARM64-T-SAME: type { i8, i8, i8, i8 } +// LAYOUT-NT-SAME: type { i8, i8 } +// LAYOUT-STRICT-NT-SAME: type { i8, i8 } +// LAYOUT-DWN32-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +struct P8 { + unsigned a : 7; + short : 0; + unsigned char b : 7; +} p8; +// CHECK-LABEL: LLVMType:%struct.P8 = +// LAYOUT-T-SAME: type { i8, i8, i8, i8 } +// LAYOUT-ARM64-T-SAME: type { i8, i8, i8, i8 } +// LAYOUT-NT-SAME: type { i16 } +// LAYOUT-STRICT-NT-SAME: type { i16 } +// LAYOUT-DWN32-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +struct P9 { + unsigned a : 7; + char : 0; + unsigned short b : 7; +} p9; +// CHECK-LABEL: LLVMType:%struct.P9 = +// LAYOUT-T-SAME: type { i8, i8, [2 x i8] } +// LAYOUT-ARM64-T-SAME: type { i8, i8 } +// LAYOUT-NT-SAME: type { i16 } +// LAYOUT-STRICT-NT-SAME: type { i16 } +// LAYOUT-DWN32-SAME: type { i8, [3 x i8], i8, [3 x i8] } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +struct __attribute__((aligned(4))) P10 { + unsigned a : 7; + unsigned short b : 7; + unsigned c : 7; + char : 0; +} p10; +// CHECK-LABEL: LLVMType:%struct.P10 = +// LAYOUT-T-SAME: type { i32 } +// LAYOUT-ARM64-T-SAME: type { i32 } +// LAYOUT-NT-SAME: type { i32 } +// LAYOUT-STRICT-NT-SAME: type { i32 } +// LAYOUT-DWN32-SAME: type { i32 } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: + +struct __attribute__((aligned(4))) P11 { + unsigned a : 7; + unsigned short b : 7; + unsigned c : 10; + char : 0; // at a char boundary +} p11; +// CHECK-LABEL: LLVMType:%struct.P11 = +// LAYOUT-T-SAME: type { i32 } +// LAYOUT-ARM64-T-SAME: type { i32 } +// LAYOUT-NT-SAME: type { i32 } +// LAYOUT-STRICT-NT-SAME: type { i32 } +// LAYOUT-DWN32-SAME: type { i32 } +// CHECK: BitFields:[ +// LAYOUT-T-NEXT: diff --git a/clang/test/CodeGen/bitfield-access-unit.c b/clang/test/CodeGen/bitfield-access-unit.c new file mode 100644 index 00000000000000..1aed2e7202fc65 --- /dev/null +++ b/clang/test/CodeGen/bitfield-access-unit.c @@ -0,0 +1,302 @@ +// Check arches with 32bit ints. (Not you, AVR & MSP430) + +// Configs that have cheap unaligned access + +// 64-bit Little Endian +// RUN: %clang_cc1 -triple=aarch64-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX64,CHECK-64,LAYOUT-64-DWN %s +// RUN: %clang_cc1 -triple=aarch64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX64,CHECK-64,LAYOUT-64,LAYOUT-64-FLEX %s +// RUN: %clang_cc1 -triple=loongarch64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX64,CHECK-64,LAYOUT-64,LAYOUT-64-FLEX %s +// RUN: %clang_cc1 -triple=ve-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX64 %s +// RUN: %clang_cc1 -triple=wasm64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX64 %s +// RUN: %clang_cc1 -triple=x86_64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX64,CHECK-64,LAYOUT-64,LAYOUT-64-FLEX %s + +// 64-bit Big Endian +// RUN: %clang_cc1 -triple=powerpc64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX64,CHECK-64,LAYOUT-64,LAYOUT-64-FLEX %s +// RUN: %clang_cc1 -triple=systemz %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX64,CHECK-64,LAYOUT-64,LAYOUT-64-FLEX %s + +// 32-bit Little Endian +// RUN: %clang_cc1 -triple=arm-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT-DWN32,LAYOUT-DWN32-FLEX %s +// RUN: %clang_cc1 -triple=arm-none-eabi %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX32 %s +// RUN: %clang_cc1 -triple=i686-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX32 %s +// RUN: %clang_cc1 -triple=powerpcle-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX32 %s +// RUN: %clang_cc1 -triple=wasm32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX32 %s + +// 32-bit Big Endian +// RUN: %clang_cc1 -triple=powerpc-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-FLEX,LAYOUT-FLEX32 %s + +// Configs that have expensive unaligned access +// 64-bit Little Endian +// RUN: %clang_cc1 -triple=aarch64-linux-gnu %s -target-feature +strict-align -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT,CHECK-64,LAYOUT-64,LAYOUT-64-STRICT %s +// RUN: %clang_cc1 -triple=amdgcn-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT,CHECK-64,LAYOUT-64,LAYOUT-64-STRICT %s +// RUN: %clang_cc1 -triple=loongarch64-elf -target-feature -ual %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT,CHECK-64,LAYOUT-64,LAYOUT-64-STRICT %s +// RUN: %clang_cc1 -triple=riscv64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT,CHECK-64,LAYOUT-64,LAYOUT-64-STRICT %s + +// 64-big Big endian +// RUN: %clang_cc1 -triple=mips64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT,CHECK-64,LAYOUT-64,LAYOUT-64-STRICT %s + +// 32-bit Little Endian +// RUN: %clang_cc1 -triple=arc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=arm-apple-darwin %s -target-feature +strict-align -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT-DWN32,LAYOUT-DWN32-STRICT %s +// RUN: %clang_cc1 -triple=arm-none-eabi %s -target-feature +strict-align -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=bpf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=csky %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=hexagon-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=loongarch32-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=nvptx-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=riscv32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=spir-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=xcore-none-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s + +// 32-bit Big Endian +// RUN: %clang_cc1 -triple=lanai-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=mips-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=sparc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s +// RUN: %clang_cc1 -triple=tce-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT-STRICT %s + +// Both le64-elf and m68-elf are strict alignment ISAs with 4-byte aligned +// 64-bit or 2-byte aligned 32-bit integer types. This more compex to describe here. + +// If unaligned access is expensive don't stick these together. +struct A { + char a : 7; + char b : 7; +} a; +// CHECK-LABEL: LLVMType:%struct.A = +// LAYOUT-FLEX-SAME: type { i16 } +// LAYOUT-STRICT-SAME: type { i8, i8 } +// LAYOUT-DWN32-SAME: type { i16 } +// CHECK: BitFields:[ +// LAYOUT-FLEX-NEXT: + +// But do here. +struct __attribute__((aligned(2))) B { + char a : 7; + char b : 7; +} b; +// CHECK-LABEL: LLVMType:%struct.B = +// LAYOUT-SAME: type { i16 } +// LAYOUT-DWN32-SAME: type { i16 } +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +// Not here -- poor alignment within struct +struct C { + int f1; + char f2; + char a : 7; + char b : 7; +} c; +// CHECK-LABEL: LLVMType:%struct.C = +// LAYOUT-FLEX-SAME: type <{ i32, i8, i16, i8 }> +// LAYOUT-STRICT-SAME: type { i32, i8, i8, i8 } +// LAYOUT-DWN32-SAME: type <{ i32, i8, i16, i8 }> +// CHECK: BitFields:[ +// LAYOUT-FLEX-NEXT: + +// Not here, we're packed +struct __attribute__((packed)) D { + int f1; + int a : 8; + int b : 8; + char _; +} d; +// CHECK-LABEL: LLVMType:%struct.D = +// LAYOUT-FLEX-SAME: type <{ i32, i16, i8 }> +// LAYOUT-STRICT-SAME: type <{ i32, i8, i8, i8 }> +// LAYOUT-DWN32-FLEX-SAME: type <{ i32, i16, i8 }> +// LAYOUT-DWN32-STRICT-SAME: type <{ i32, i8, i8, i8 }> +// CHECK: BitFields:[ +// LAYOUT-FLEX-NEXT: + +struct E { + char a : 7; + short b : 13; + unsigned c : 12; +} e; +// CHECK-LABEL: LLVMType:%struct.E = +// LAYOUT-FLEX64-SAME: type { i64 } +// LAYOUT-FLEX32-SAME: type { i32, i16 } +// LAYOUT-STRICT-SAME: type { i32, i16 } +// LAYOUT-DWN32-SAME: type { i32 } +// CHECK: BitFields:[ +// LAYOUT-FLEX64-NEXT: + +struct F { + char a : 7; + short b : 13; + unsigned c : 12; + signed char d : 7; +} f; +// CHECK-LABEL: LLVMType:%struct.F = +// LAYOUT-FLEX64-SAME: type { i64 } +// LAYOUT-FLEX32-SAME: type { i32, i32 } +// LAYOUT-STRICT-SAME: type { i32, i32 } +// LAYOUT-DWN32-SAME: type <{ i32, i8 }> +// CHECK: BitFields:[ +// LAYOUT-FLEX64-NEXT: + +struct G { + char a : 7; + short b : 13; + unsigned c : 12; + signed char d : 7; + signed char e; +} g; +// CHECK-LABEL: LLVMType:%struct.G = +// LAYOUT-SAME: type { i32, i16, i8, i8 } +// LAYOUT-DWN32-SAME: type <{ i32, i8, i8 }> +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +#if _LP64 +struct A64 { + int a : 16; + short b : 8; + long c : 16; + int d : 16; + signed char e : 8; +} a64; +// CHECK-64-LABEL: LLVMType:%struct.A64 = +// LAYOUT-64-SAME: type { i64 } +// LAYOUT-64-DWN-SAME: type { i64 } +// CHECK-64: BitFields:[ +// LAYOUT-64-NEXT: + +struct B64 { + int a : 16; + short b : 8; + long c : 16; + int d : 16; + signed char e; // not a bitfield +} b64; +// CHECK-64-LABEL: LLVMType:%struct.B64 = +// LAYOUT-64-FLEX-SAME: type <{ i16, i8, i32, i8 }> +// LAYOUT-64-STRICT-SAME: type <{ i16, i8, i16, i16, i8 }> +// LAYOUT-64-DWN-SAME: type <{ i16, i8, i32, i8 }> +// CHECK-64: BitFields:[ +// LAYOUT-64-FLEX-NEXT: + +struct C64 { + int a : 15; + short b : 8; + long c : 16; + int d : 15; + signed char e : 7; +} c64; +// CHECK-64-LABEL: LLVMType:%struct.C64 = +// LAYOUT-64-SAME: type { i64 } +// LAYOUT-64-DWN-SAME: type { i64 } +// CHECK-64: BitFields:[ +// LAYOUT-64-NEXT: + +#endif diff --git a/clang/test/CodeGen/debug-info-bitfield-0-struct.c b/clang/test/CodeGen/debug-info-bitfield-0-struct.c index 0535b626771429..9fadf898e34661 100644 --- a/clang/test/CodeGen/debug-info-bitfield-0-struct.c +++ b/clang/test/CodeGen/debug-info-bitfield-0-struct.c @@ -101,8 +101,10 @@ struct None_B { int y : 4; }; -struct None_C { - // BOTH-DAG: ![[NONE_C:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "None_C", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 32, elements: ![[NONE_C_ELEMENTS:[0-9]+]]) +// AMDGCN does not do unaligned access cheaply, so the bitfield access units +// would remain single bytes, without the aligned attribure +struct __attribute__((aligned(4))) None_C { + // BOTH-DAG: ![[NONE_C:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "None_C", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 32, align: 32, elements: ![[NONE_C_ELEMENTS:[0-9]+]]) // BOTH-DAG: ![[NONE_C_ELEMENTS]] = !{![[NONE_C_X:[0-9]+]], ![[NONE_C_Y:[0-9]+]], ![[NONE_C_A:[0-9]+]], ![[NONE_C_B:[0-9]+]]} // BOTH-DAG: ![[NONE_C_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: ![[NONE_C]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 8, flags: DIFlagBitField, extraData: i64 0) // BOTH-DAG: ![[NONE_C_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: ![[NONE_C]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 8, offset: 8, flags: DIFlagBitField, extraData: i64 0) diff --git a/clang/test/CodeGen/no-bitfield-type-align.c b/clang/test/CodeGen/no-bitfield-type-align.c index 53ed5e9ad8f854..1861c6886a35b3 100644 --- a/clang/test/CodeGen/no-bitfield-type-align.c +++ b/clang/test/CodeGen/no-bitfield-type-align.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -fno-bitfield-type-align -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -fno-bitfield-type-align -fdump-record-layouts-simple -emit-llvm -o %t %s | FileCheck %s -check-prefix=LAYOUT +// RUN: FileCheck %s <%t struct S { unsigned short: 0; @@ -7,6 +8,13 @@ struct S { unsigned short f2:15; }; +// LAYOUT-LABEL: LLVMType:%struct.S = +// LAYOUT-SAME: type { i32 } +// LAYOUT: BitFields:[ +// LAYOUT-NEXT: + // CHECK: define{{.*}} void @test_zero_width_bitfield(ptr noundef %[[A:.*]]) // CHECK: %[[BF_LOAD:.*]] = load i32, ptr %[[V1:.*]], align 1 // CHECK: %[[BF_CLEAR:.*]] = and i32 %[[BF_LOAD]], 32767 diff --git a/clang/test/CodeGen/struct-x86-darwin.c b/clang/test/CodeGen/struct-x86-darwin.c index 5191441cabaf04..e79ecefb880dfb 100644 --- a/clang/test/CodeGen/struct-x86-darwin.c +++ b/clang/test/CodeGen/struct-x86-darwin.c @@ -1,25 +1,70 @@ -// RUN: %clang_cc1 %s -emit-llvm -triple=i686-apple-darwin9 -o - | FileCheck %s -// CHECK: STest1 = type { i32, [4 x i16], double } -// CHECK: STest2 = type { i16, i16, i32, i32 } -// CHECK: STest3 = type { i8, i16, i32 } -// CHECK: STestB1 = type { i8, i8 } -// CHECK: STestB2 = type { i8, i8, i8 } -// CHECK: STestB3 = type { i8, i8 } -// CHECK: STestB4 = type { i8, i8, i8, i8 } -// CHECK: STestB5 = type { i8, i16, i8 } -// CHECK: STestB6 = type { i8, i8, i16 } +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null -triple=i686-apple-darwin9 -fdump-record-layouts-simple | FileCheck %s + // Test struct layout for x86-darwin target struct STest1 {int x; short y[4]; double z; } st1; struct STest2 {short a,b; int c,d; } st2; struct STest3 {char a; short b; int c; } st3; -// Bitfields +// Bitfields struct STestB1 {char a; char b:2; } stb1; struct STestB2 {char a; char b:5; char c:4; } stb2; struct STestB3 {char a; char b:2; } stb3; struct STestB4 {char a; short b:2; char c; } stb4; struct STestB5 {char a; short b:10; char c; } stb5; -struct STestB6 {int a:1; char b; int c:13 } stb6; +struct STestB6 {int a:1; char b; int c:13; } stb6; // Packed struct STestP1 {char a; short b; int c; } __attribute__((__packed__)) stp1; + +// CHECK-LABEL: LLVMType:%struct.STest1 = +// CHECK-SAME: type { i32, [4 x i16], double } +// CHECK: BitFields:[ +// CHECK-NEXT: ]> + +// CHECK-LABEL: LLVMType:%struct.STest2 = +// CHECK-SAME: type { i16, i16, i32, i32 } +// CHECK: BitFields:[ +// CHECK-NEXT: ]> + +// CHECK-LABEL: LLVMType:%struct.STest3 = +// CHECK-SAME: type { i8, i16, i32 } +// CHECK: BitFields:[ +// CHECK-NEXT: ]> + +// CHECK-LABEL: LLVMType:%struct.STestB1 = +// CHECK-SAME: type { i8, i8 } +// CHECK: BitFields:[ +// CHECK-NEXT: + +// CHECK-LABEL: LLVMType:%struct.STestB2 = +// CHECK-SAME: type <{ i8, i16 }> +// CHECK: BitFields:[ +// CHECK-NEXT: + +// CHECK-LABEL: LLVMType:%struct.STestB3 = +// CHECK-SAME: type { i8, i8 } +// CHECK: BitFields:[ +// CHECK-NEXT: + +// CHECK-LABEL: LLVMType:%struct.STestB4 = +// CHECK-SAME: type { i8, i8, i8, i8 } +// CHECK: BitFields:[ +// CHECK-NEXT: + +// CHECK-LABEL: LLVMType:%struct.STestB5 = +// CHECK-SAME: type { i8, i16, i8 } +// CHECK: BitFields:[ +// CHECK-NEXT: + +// CHECK-LABEL: LLVMType:%struct.STestB6 = +// CHECK-SAME: type { i8, i8, i16 } +// CHECK: BitFields:[ +// CHECK-NEXT: diff --git a/clang/test/CodeGen/tbaa-struct.cpp b/clang/test/CodeGen/tbaa-struct.cpp index 9b4b7415142d93..ca076ce5aa2732 100644 --- a/clang/test/CodeGen/tbaa-struct.cpp +++ b/clang/test/CodeGen/tbaa-struct.cpp @@ -197,7 +197,7 @@ void copy12(UnionMember2 *a1, UnionMember2 *a2) { // CHECK-OLD: [[TS6]] = !{i64 0, i64 2, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]} // CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0} // CHECK-OLD [[DOUBLE]] = !{!"double", [[CHAR]], i64 0} -// CHECK-OLD: [[TS7]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 3, i64 1, [[TAG_CHAR]], i64 4, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]], i64 16, i64 1, [[TAG_CHAR]]} +// CHECK-OLD: [[TS7]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 3, i64 2, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]], i64 16, i64 1, [[TAG_CHAR]]} // CHECK-OLD: [[TS8]] = !{i64 0, i64 4, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]]} // CHECK-OLD: [[TS9]] = !{i64 0, i64 8, [[TAG_CHAR]], i64 8, i64 4, [[TAG_INT]]} // CHECK-OLD: [[TS10]] = !{i64 0, i64 4, [[TAG_INT]], i64 8, i64 8, [[TAG_CHAR]]} diff --git a/clang/test/CodeGenCXX/bitfield-access-empty.cpp b/clang/test/CodeGenCXX/bitfield-access-empty.cpp new file mode 100644 index 00000000000000..c5e6f55ffa6964 --- /dev/null +++ b/clang/test/CodeGenCXX/bitfield-access-empty.cpp @@ -0,0 +1,150 @@ +// Check if we can merge bitfields across empty members + +// Configs that have cheap unaligned access +// Little Endian +// RUN: %clang_cc1 -triple=aarch64-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=aarch64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=arm-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT-DWN32 %s +// RUN: %clang_cc1 -triple=arm-none-eabi %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=i686-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=loongarch64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=powerpcle-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=ve-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=wasm32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=wasm64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=x86_64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s + +// Big Endian +// RUN: %clang_cc1 -triple=powerpc-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=powerpc64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=systemz %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s + +// Configs that have expensive unaligned access +// Little Endian +// RUN: %clang_cc1 -triple=amdgcn-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=arc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=bpf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=csky %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=hexagon-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=le64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=loongarch32-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=nvptx-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=riscv32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=riscv64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=spir-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=xcore-none-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s + +// Big endian +// RUN: %clang_cc1 -triple=lanai-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=m68k-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=mips-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=mips64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=sparc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s +// RUN: %clang_cc1 -triple=tce-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT %s + +struct Empty {}; + +struct P1 { + unsigned a : 16; + [[no_unique_address]] Empty e; + unsigned b : 16; +} p1; +// CHECK-LABEL: LLVMType:%struct.P1 = +// LAYOUT-SAME: type { i16, i16 } +// LAYOUT-DWN32-SAME: type { i16, i16 } +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P1 = +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +struct P2 { + unsigned a : 15; + [[no_unique_address]] Empty e; + unsigned b : 15; +} p2; +// CHECK-LABEL: LLVMType:%struct.P2 = +// LAYOUT-SAME: type { i16, i16 } +// LAYOUT-DWN32-SAME: type { i16, i16 } +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P2 = +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +struct P3 { + unsigned a : 16; + Empty e; + unsigned b : 16; +} p3; +// CHECK-LABEL: LLVMType:%struct.P3 = +// LAYOUT-SAME: type { i16, %struct.Empty, i16, [2 x i8] } +// LAYOUT-DWN32-SAME: type <{ i16, %struct.Empty, i16 }> +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P3 = +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +struct P4 { + unsigned : 0; +} p4; +// CHECK-LABEL: LLVMType:%struct.P4 = +// LAYOUT-SAME: type { {{.+}} } +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P4 = +// CHECK: BitFields:[ +// CHECK-NEXT: ]> + +struct P5 { + ~P5(); + unsigned : 0; +} p5; +// CHECK-LABEL: LLVMType:%struct.P5 = +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P5.base = type {} +// CHECK: BitFields:[ +// CHECK-NEXT: ]> + +struct P6 { + unsigned a : 16; + unsigned b : 8; + [[no_unique_address]] Empty e; + unsigned c; +} p6; +// CHECK-LABEL: LLVMType:%struct.P6 = +// LAYOUT-SAME: type { i32, i32 } +// LAYOUT-DWN32-SAME: type { i32, i32 } +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P6 = +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +struct P7 { + unsigned a : 16; + unsigned b : 8; + Empty e; + unsigned c; +} p7; +// CHECK-LABEL: LLVMType:%struct.P7 = +// LAYOUT-SAME: type { i16, i8, %struct.Empty, i32 } +// LAYOUT-DWN32-SAME: type { i16, i8, %struct.Empty, i32 } +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.P7 = +// CHECK: BitFields:[ +// LAYOUT-NEXT: diff --git a/clang/test/CodeGenCXX/bitfield-access-tail.cpp b/clang/test/CodeGenCXX/bitfield-access-tail.cpp new file mode 100644 index 00000000000000..1539e17cad4369 --- /dev/null +++ b/clang/test/CodeGenCXX/bitfield-access-tail.cpp @@ -0,0 +1,157 @@ +// Check we use tail padding if it is known to be safe + +// Configs that have cheap unaligned access +// Little Endian +// RUN: %clang_cc1 -triple=aarch64-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=aarch64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=arm-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT-DWN32 %s +// RUN: %clang_cc1 -triple=arm-none-eabi %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=i686-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=loongarch64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=powerpcle-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=ve-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=wasm32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=wasm64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=x86_64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s + +// Big Endian +// RUN: %clang_cc1 -triple=powerpc-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=powerpc64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=systemz %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s + +// Configs that have expensive unaligned access +// Little Endian +// RUN: %clang_cc1 -triple=amdgcn-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=arc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=bpf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=csky %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=hexagon-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=le64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=loongarch32-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=nvptx-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=riscv32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=riscv64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=spir-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=xcore-none-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s + +// Big endian +// RUN: %clang_cc1 -triple=lanai-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=m68k-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=mips-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=mips64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s +// RUN: %clang_cc1 -triple=sparc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s +// RUN: %clang_cc1 -triple=tce-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s + +// Can use tail padding +struct Pod { + int a : 16; + int b : 8; +} P; +// CHECK-LABEL: LLVMType:%struct.Pod = +// LAYOUT-SAME: type { i32 } +// LAYOUT-DWN32-SAME: type <{ i16, i8 }> +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.Pod = +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +// No tail padding +struct __attribute__((packed)) PPod { + int a : 16; + int b : 8; +} PP; +// CHECK-LABEL: LLVMType:%struct.PPod = +// LAYOUT-SAME: type <{ i16, i8 }> +// LAYOUT-DWN32-SAME: type <{ i16, i8 }> +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.PPod = +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +// Cannot use tail padding +struct NonPod { + ~NonPod(); + int a : 16; + int b : 8; +} NP; +// CHECK-LABEL: LLVMType:%struct.NonPod = +// LAYOUT-SAME: type <{ i16, i8, i8 }> +// LAYOUT-DWN32-SAME: type <{ i16, i8 }> +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct. +// LAYOUT-SAME: NonPod.base = type <{ i16, i8 }> +// LAYOUT-DWN32-SAME: NonPod = type <{ i16, i8 }> +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +// No tail padding +struct __attribute__((packed)) PNonPod { + ~PNonPod(); + int a : 16; + int b : 8; +} PNP; +// CHECK-LABEL: LLVMType:%struct.PNonPod = +// LAYOUT-SAME: type <{ i16, i8 }> +// LAYOUT-DWN32-SAME: type <{ i16, i8 }> +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.PNonPod = +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +struct __attribute__((aligned(4))) Empty {} empty; + +struct Char { char a; } cbase; +struct D : virtual Char { + [[no_unique_address]] Empty e0; + [[no_unique_address]] Empty e1; + unsigned a : 24; // keep as 24bits +} d; +// CHECK-LABEL: LLVMType:%struct.D = +// LAYOUT64-SAME: type <{ ptr, [3 x i8], %struct.Char, [4 x i8] }> +// LAYOUT32-SAME: type { ptr, [3 x i8], %struct.Char } +// LAYOUT-DWN32-SAME: type { ptr, [3 x i8], %struct.Char } +// CHECK-NEXT: NonVirtualBaseLLVMType: +// LAYOUT64-SAME: %struct.D.base = type <{ ptr, i32 }> +// LAYOUT32-SAME: %struct.D = type { ptr, [3 x i8], %struct.Char } +// LAYOUT-DWN32-SAME: %struct.D = type { ptr, [3 x i8], %struct.Char } +// CHECK: BitFields:[ +// LAYOUT-NEXT: + +struct Int { int a; } ibase; +struct E : virtual Int { + [[no_unique_address]] Empty e0; + [[no_unique_address]] Empty e1; + unsigned a : 24; // expand to 32 +} e; +// CHECK-LABEL: LLVMType:%struct.E = +// LAYOUT64-SAME: type <{ ptr, i32, %struct.Int }> +// LAYOUT32-SAME: type { ptr, i32, %struct.Int } +// LAYOUT-DWN32-SAME: type { ptr, i32, %struct.Int } +// CHECK-NEXT: NonVirtualBaseLLVMType:%struct.E.base = +// LAYOUT64-SAME: type <{ ptr, i32 }> +// LAYOUT32-SAME: type { ptr, i32 } +// LAYOUT-DWN32-SAME: type { ptr, i32 } +// CHECK: BitFields:[ +// LAYOUT-NEXT: diff --git a/clang/test/CodeGenCXX/bitfield-ir.cpp b/clang/test/CodeGenCXX/bitfield-ir.cpp new file mode 100644 index 00000000000000..76c144072da686 --- /dev/null +++ b/clang/test/CodeGenCXX/bitfield-ir.cpp @@ -0,0 +1,101 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// RUN: %clang_cc1 -triple x86_64-linux-gnu -O2 -emit-llvm -o - %s | FileCheck %s + +struct Tail { + ~Tail(); + int a : 16; + int b : 8; +}; + +struct Char { + int a : 16; + int b : 8; + char c; +}; + +struct Int { + int a : 16; + int b : 8; + int c; +}; + + +// CHECK-LABEL: define dso_local void @_Z1AP4Tail +// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[P]], align 4 +// CHECK-NEXT: [[INC:%.*]] = add i16 [[BF_LOAD]], 1 +// CHECK-NEXT: store i16 [[INC]], ptr [[P]], align 4 +// CHECK-NEXT: ret void +// +void A (Tail *p) { + p->a++; +} + +// CHECK-LABEL: define dso_local void @_Z1BP4Tail +// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 2 +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[B]], align 2 +// CHECK-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 +// CHECK-NEXT: store i8 [[INC]], ptr [[B]], align 2 +// CHECK-NEXT: ret void +// +void B (Tail *p) { + p->b++; +} + +// CHECK-LABEL: define dso_local void @_Z1AP4Char +// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[P]], align 4 +// CHECK-NEXT: [[INC:%.*]] = add i16 [[BF_LOAD]], 1 +// CHECK-NEXT: store i16 [[INC]], ptr [[P]], align 4 +// CHECK-NEXT: ret void +// +void A (Char *p) { + p->a++; +} + +// CHECK-LABEL: define dso_local void @_Z1BP4Char +// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 2 +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[B]], align 2 +// CHECK-NEXT: [[INC:%.*]] = add i8 [[BF_LOAD]], 1 +// CHECK-NEXT: store i8 [[INC]], ptr [[B]], align 2 +// CHECK-NEXT: ret void +// +void B (Char *p) { + p->b++; +} + +// CHECK-LABEL: define dso_local void @_Z1AP3Int +// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[P]], align 4 +// CHECK-NEXT: [[INC:%.*]] = add i32 [[BF_LOAD]], 1 +// CHECK-NEXT: [[BF_VALUE:%.*]] = and i32 [[INC]], 65535 +// CHECK-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -65536 +// CHECK-NEXT: [[BF_SET:%.*]] = or disjoint i32 [[BF_VALUE]], [[BF_CLEAR]] +// CHECK-NEXT: store i32 [[BF_SET]], ptr [[P]], align 4 +// CHECK-NEXT: ret void +// +void A (Int *p) { + p->a++; +} + +// CHECK-LABEL: define dso_local void @_Z1BP3Int +// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[P]], align 4 +// CHECK-NEXT: [[BF_VALUE:%.*]] = add i32 [[BF_LOAD]], 65536 +// CHECK-NEXT: [[BF_SHL2:%.*]] = and i32 [[BF_VALUE]], 16711680 +// CHECK-NEXT: [[BF_CLEAR:%.*]] = and i32 [[BF_LOAD]], -16711681 +// CHECK-NEXT: [[BF_SET:%.*]] = or disjoint i32 [[BF_SHL2]], [[BF_CLEAR]] +// CHECK-NEXT: store i32 [[BF_SET]], ptr [[P]], align 4 +// CHECK-NEXT: ret void +// +void B (Int *p) { + p->b++; +} diff --git a/clang/test/CodeGenCXX/bitfield.cpp b/clang/test/CodeGenCXX/bitfield.cpp index a478eb44915e7a..7545e02840e6b2 100644 --- a/clang/test/CodeGenCXX/bitfield.cpp +++ b/clang/test/CodeGenCXX/bitfield.cpp @@ -1,7 +1,9 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s \ -// RUN: | FileCheck -check-prefix=CHECK-X86-64 %s -// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm -o - %s \ -// RUN: | FileCheck -check-prefix=CHECK-PPC64 %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fdump-record-layouts-simple \ +// RUN: -emit-llvm -o %t %s | FileCheck -check-prefixes=LAYOUT,LAYOUT-X86-64 %s +// RUN: FileCheck -check-prefix=CHECK-X86-64 %s <%t +// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -fdump-record-layouts-simple\ +// RUN: -emit-llvm -o %t %s | FileCheck -check-prefixes=LAYOUT,LAYOUT-PPC64 %s +// RUN: FileCheck -check-prefix=CHECK-PPC64 %s <%t // // Tests for bitfield access patterns in C++ with special attention to // conformance to C++11 memory model requirements. @@ -19,6 +21,27 @@ namespace N0 { unsigned b70 : 6; unsigned b71 : 2; }; +// LAYOUT-LABEL: LLVMType:%"struct.N0::S" = +// LAYOUT-SAME: type { i64 } +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + unsigned read00(S* s) { // CHECK-X86-64-LABEL: define{{.*}} i32 @_ZN2N06read00 // CHECK-X86-64: %[[val:.*]] = load i64, ptr %{{.*}} @@ -149,6 +172,13 @@ namespace N1 { unsigned b : 1; char c; }; +// LAYOUT-LABEL: LLVMType:%"struct.N1::S" = +// LAYOUT-SAME: type { i8, i8, i8, i8 } +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + unsigned read(S* s) { // CHECK-X86-64-LABEL: define{{.*}} i32 @_ZN2N14read // CHECK-X86-64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}, ptr %{{.*}}, i32 0, i32 1 @@ -193,6 +223,13 @@ namespace N2 { unsigned b : 24; void *p; }; +// LAYOUT-LABEL: LLVMType:%"struct.N2::S" = +// LAYOUT-SAME: type { i32, ptr } +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + unsigned read(S* s) { // CHECK-X86-64-LABEL: define{{.*}} i32 @_ZN2N24read // CHECK-X86-64: %[[val:.*]] = load i32, ptr %{{.*}} @@ -230,6 +267,13 @@ namespace N3 { struct S { unsigned b : 24; }; +// LAYOUT-LABEL: LLVMType:%"struct.N3::S" = +// LAYOUT-SAME: type { i32 } +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + unsigned read(S* s) { // CHECK-X86-64-LABEL: define{{.*}} i32 @_ZN2N34read // CHECK-X86-64: %[[val:.*]] = load i32, ptr %{{.*}} @@ -276,6 +320,14 @@ namespace N4 { char c; }; #endif +// LAYOUT-LABEL: LLVMType:%"struct.N4::Base" = +// LAYOUT-SAME: type <{ ptr, [3 x i8], [5 x i8] }> +// LAYOUT-NEXT: NonVirtualBaseLLVMType:%"struct.N4::Base.base" = type <{ ptr, [3 x i8] }> +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + unsigned read(Base* s) { // FIXME: We should widen this load as long as the function isn't being // instrumented by ThreadSanitizer. @@ -317,6 +369,22 @@ namespace N5 { struct X { unsigned b : 24; char c; } x; struct Y { unsigned b : 24; } y; }; +// LAYOUT-LABEL: LLVMType:%"struct.N5::U::X" = +// LAYOUT-SAME: type { [3 x i8], i8 } +// LAYOUT-NEXT: NonVirtualBaseLLVMType:%"struct.N5::U::X" = +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + +// LAYOUT-LABEL: LLVMType:%"struct.N5::U::Y" = +// LAYOUT-SAME: type { i32 } +// LAYOUT-NEXT: NonVirtualBaseLLVMType:%"struct.N5::U::Y" = +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + unsigned read(U* u) { // CHECK-X86-64-LABEL: define{{.*}} i32 @_ZN2N54read // CHECK-X86-64: %[[val:.*]] = load i32, ptr %{{.*}} @@ -360,6 +428,15 @@ namespace N6 { unsigned char : 0; unsigned char b2 : 8; }; +// LAYOUT-LABEL: LLVMType:%"struct.N6::S" = +// LAYOUT-SAME: type { [3 x i8], i8 } +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + unsigned read(S* s) { // CHECK-X86-64-LABEL: define{{.*}} i32 @_ZN2N64read // CHECK-X86-64: %[[val1:.*]] = load i24, ptr %{{.*}} @@ -416,6 +493,22 @@ namespace N7 { char c; }; #endif +// LAYOUT-LABEL: LLVMType:%"struct.N7::B1" = +// LAYOUT-SAME: type <{ ptr, [3 x i8], [5 x i8] }> +// LAYOUT-NEXT: NonVirtualBaseLLVMType:%"struct.N7::B1.base" = type <{ ptr, [3 x i8] }> +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + +// LAYOUT-LABEL: LLVMType:%"struct.N7::B2" = +// LAYOUT-SAME: type <{ ptr, [3 x i8], [5 x i8], %"struct.N7::B1.base", [5 x i8] }> +// LAYOUT-NEXT: NonVirtualBaseLLVMType:%"struct.N7::B2.base" = type <{ ptr, [3 x i8] }> +// LAYOUT: BitFields:[ +// LAYOUT-X86-64-NEXT: + unsigned read(B2* s) { // FIXME: We should widen this load as long as the function isn't being // instrumented by ThreadSanitizer. diff --git a/clang/test/CodeGenHLSL/ArrayTemporary.hlsl b/clang/test/CodeGenHLSL/ArrayTemporary.hlsl new file mode 100644 index 00000000000000..63a30b61440eb5 --- /dev/null +++ b/clang/test/CodeGenHLSL/ArrayTemporary.hlsl @@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + +void fn(float x[2]) { } + +// CHECK-LABEL: define void {{.*}}call{{.*}} +// CHECK: [[Arr:%.*]] = alloca [2 x float] +// CHECK: [[Tmp:%.*]] = alloca [2 x float] +// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr]], i8 0, i32 8, i1 false) +// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 8, i1 false) +// CHECK: call void {{.*}}fn{{.*}}(ptr noundef byval([2 x float]) align 4 [[Tmp]]) +void call() { + float Arr[2] = {0, 0}; + fn(Arr); +} + +struct Obj { + float V; + int X; +}; + +void fn2(Obj O[4]) { } + +// CHECK-LABEL: define void {{.*}}call2{{.*}} +// CHECK: [[Arr:%.*]] = alloca [4 x %struct.Obj] +// CHECK: [[Tmp:%.*]] = alloca [4 x %struct.Obj] +// CHECK: call void @llvm.memset.p0.i32(ptr align 4 [[Arr]], i8 0, i32 32, i1 false) +// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 32, i1 false) +// CHECK: call void {{.*}}fn2{{.*}}(ptr noundef byval([4 x %struct.Obj]) align 4 [[Tmp]]) +void call2() { + Obj Arr[4] = {}; + fn2(Arr); +} + + +void fn3(float x[2][2]) { } + +// CHECK-LABEL: define void {{.*}}call3{{.*}} +// CHECK: [[Arr:%.*]] = alloca [2 x [2 x float]] +// CHECK: [[Tmp:%.*]] = alloca [2 x [2 x float]] +// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Arr]], ptr align 4 {{.*}}, i32 16, i1 false) +// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 16, i1 false) +// CHECK: call void {{.*}}fn3{{.*}}(ptr noundef byval([2 x [2 x float]]) align 4 [[Tmp]]) +void call3() { + float Arr[2][2] = {{0, 0}, {1,1}}; + fn3(Arr); +} + +// CHECK-LABEL: define void {{.*}}call4{{.*}}(ptr +// CHECK-SAME: noundef byval([2 x [2 x float]]) align 4 [[Arr:%.*]]) +// CHECK: [[Tmp:%.*]] = alloca [2 x [2 x float]] +// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[Arr]], i32 16, i1 false) +// CHECK: call void {{.*}}fn3{{.*}}(ptr noundef byval([2 x [2 x float]]) align 4 [[Tmp]]) + +void call4(float Arr[2][2]) { + fn3(Arr); +} + +// Verify that each template instantiation codegens to a unique and correctly +// mangled function name. + +// CHECK-LABEL: define void {{.*}}template_call{{.*}}(ptr + +// CHECK-SAME: noundef byval([2 x float]) align 4 [[FA2:%[0-9A-Z]+]], +// CHECK-SAME: ptr noundef byval([4 x float]) align 4 [[FA4:%[0-9A-Z]+]], +// CHECK-SAME: ptr noundef byval([3 x i32]) align 4 [[IA3:%[0-9A-Z]+]] + +// CHECK: [[Tmp1:%.*]] = alloca [2 x float] +// CHECK: [[Tmp2:%.*]] = alloca [4 x float] +// CHECK: [[Tmp3:%.*]] = alloca [3 x i32] +// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp1]], ptr align 4 [[FA2]], i32 8, i1 false) +// CHECK: call void @"??$template_fn@$$BY01M@@YAXY01M@Z"(ptr noundef byval([2 x float]) align 4 [[Tmp1]]) +// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp2]], ptr align 4 [[FA4]], i32 16, i1 false) +// CHECK: call void @"??$template_fn@$$BY03M@@YAXY03M@Z"(ptr noundef byval([4 x float]) align 4 [[Tmp2]]) +// CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp3]], ptr align 4 [[IA3]], i32 12, i1 false) +// CHECK: call void @"??$template_fn@$$BY02H@@YAXY02H@Z"(ptr noundef byval([3 x i32]) align 4 [[Tmp3]]) + +template +void template_fn(T Val) {} + +void template_call(float FA2[2], float FA4[4], int IA3[3]) { + template_fn(FA2); + template_fn(FA4); + template_fn(IA3); +} + + +// Verify that Array parameter element access correctly codegens. +// CHECK-LABEL: define void {{.*}}element_access{{.*}}(ptr +// CHECK-SAME: noundef byval([2 x float]) align 4 [[FA2:%[0-9A-Z]+]] + +// CHECK: [[Addr:%.*]] = getelementptr inbounds [2 x float], ptr [[FA2]], i32 0, i32 0 +// CHECK: [[Tmp:%.*]] = load float, ptr [[Addr]] +// CHECK: call void @"??$template_fn@M@@YAXM@Z"(float noundef [[Tmp]]) + +// CHECK: [[Idx0:%.*]] = getelementptr inbounds [2 x float], ptr [[FA2]], i32 0, i32 0 +// CHECK: [[Val0:%.*]] = load float, ptr [[Idx0]] +// CHECK: [[Sum:%.*]] = fadd float [[Val0]], 5.000000e+00 +// CHECK: [[Idx1:%.*]] = getelementptr inbounds [2 x float], ptr [[FA2]], i32 0, i32 1 +// CHECK: store float [[Sum]], ptr [[Idx1]] + +void element_access(float FA2[2]) { + template_fn(FA2[0]); + FA2[1] = FA2[0] + 5; +} diff --git a/clang/test/CodeGenHLSL/builtins/round.hlsl b/clang/test/CodeGenHLSL/builtins/round.hlsl index b9f35bd3712d18..33d761dbdfbeae 100644 --- a/clang/test/CodeGenHLSL/builtins/round.hlsl +++ b/clang/test/CodeGenHLSL/builtins/round.hlsl @@ -7,47 +7,47 @@ // RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF // NATIVE_HALF: define noundef half @ -// NATIVE_HALF: %elt.round = call half @llvm.round.f16( -// NATIVE_HALF: ret half %elt.round +// NATIVE_HALF: %elt.roundeven = call half @llvm.roundeven.f16( +// NATIVE_HALF: ret half %elt.roundeven // NO_HALF: define noundef float @"?test_round_half@@YA$halff@$halff@@Z"( -// NO_HALF: %elt.round = call float @llvm.round.f32( -// NO_HALF: ret float %elt.round +// NO_HALF: %elt.roundeven = call float @llvm.roundeven.f32( +// NO_HALF: ret float %elt.roundeven half test_round_half(half p0) { return round(p0); } // NATIVE_HALF: define noundef <2 x half> @ -// NATIVE_HALF: %elt.round = call <2 x half> @llvm.round.v2f16 -// NATIVE_HALF: ret <2 x half> %elt.round +// NATIVE_HALF: %elt.roundeven = call <2 x half> @llvm.roundeven.v2f16 +// NATIVE_HALF: ret <2 x half> %elt.roundeven // NO_HALF: define noundef <2 x float> @ -// NO_HALF: %elt.round = call <2 x float> @llvm.round.v2f32( -// NO_HALF: ret <2 x float> %elt.round +// NO_HALF: %elt.roundeven = call <2 x float> @llvm.roundeven.v2f32( +// NO_HALF: ret <2 x float> %elt.roundeven half2 test_round_half2(half2 p0) { return round(p0); } // NATIVE_HALF: define noundef <3 x half> @ -// NATIVE_HALF: %elt.round = call <3 x half> @llvm.round.v3f16 -// NATIVE_HALF: ret <3 x half> %elt.round +// NATIVE_HALF: %elt.roundeven = call <3 x half> @llvm.roundeven.v3f16 +// NATIVE_HALF: ret <3 x half> %elt.roundeven // NO_HALF: define noundef <3 x float> @ -// NO_HALF: %elt.round = call <3 x float> @llvm.round.v3f32( -// NO_HALF: ret <3 x float> %elt.round +// NO_HALF: %elt.roundeven = call <3 x float> @llvm.roundeven.v3f32( +// NO_HALF: ret <3 x float> %elt.roundeven half3 test_round_half3(half3 p0) { return round(p0); } // NATIVE_HALF: define noundef <4 x half> @ -// NATIVE_HALF: %elt.round = call <4 x half> @llvm.round.v4f16 -// NATIVE_HALF: ret <4 x half> %elt.round +// NATIVE_HALF: %elt.roundeven = call <4 x half> @llvm.roundeven.v4f16 +// NATIVE_HALF: ret <4 x half> %elt.roundeven // NO_HALF: define noundef <4 x float> @ -// NO_HALF: %elt.round = call <4 x float> @llvm.round.v4f32( -// NO_HALF: ret <4 x float> %elt.round +// NO_HALF: %elt.roundeven = call <4 x float> @llvm.roundeven.v4f32( +// NO_HALF: ret <4 x float> %elt.roundeven half4 test_round_half4(half4 p0) { return round(p0); } // CHECK: define noundef float @ -// CHECK: %elt.round = call float @llvm.round.f32( -// CHECK: ret float %elt.round +// CHECK: %elt.roundeven = call float @llvm.roundeven.f32( +// CHECK: ret float %elt.roundeven float test_round_float(float p0) { return round(p0); } // CHECK: define noundef <2 x float> @ -// CHECK: %elt.round = call <2 x float> @llvm.round.v2f32 -// CHECK: ret <2 x float> %elt.round +// CHECK: %elt.roundeven = call <2 x float> @llvm.roundeven.v2f32 +// CHECK: ret <2 x float> %elt.roundeven float2 test_round_float2(float2 p0) { return round(p0); } // CHECK: define noundef <3 x float> @ -// CHECK: %elt.round = call <3 x float> @llvm.round.v3f32 -// CHECK: ret <3 x float> %elt.round +// CHECK: %elt.roundeven = call <3 x float> @llvm.roundeven.v3f32 +// CHECK: ret <3 x float> %elt.roundeven float3 test_round_float3(float3 p0) { return round(p0); } // CHECK: define noundef <4 x float> @ -// CHECK: %elt.round = call <4 x float> @llvm.round.v4f32 -// CHECK: ret <4 x float> %elt.round +// CHECK: %elt.roundeven = call <4 x float> @llvm.roundeven.v4f32 +// CHECK: ret <4 x float> %elt.roundeven float4 test_round_float4(float4 p0) { return round(p0); } diff --git a/clang/test/CodeGenHLSL/convergent-functions.hlsl b/clang/test/CodeGenHLSL/convergent-functions.hlsl new file mode 100644 index 00000000000000..f7c8b642272b1e --- /dev/null +++ b/clang/test/CodeGenHLSL/convergent-functions.hlsl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.4-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + +void fn() { +}; + +// CHECK: define{{.*| }}void {{.*}}fn{{.*}}() +// CHECK-SAME: #[[Attr:[0-9]+]] +// CHECK: attributes #[[Attr]] = { {{[^}]*}}convergent{{[^}]*}} } diff --git a/clang/test/Driver/Inputs/in.so b/clang/test/Driver/Inputs/in.so deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/clang/test/Driver/Inputs/in.so +++ /dev/null @@ -1 +0,0 @@ - diff --git a/clang/test/Driver/Inputs/libomptarget/libomptarget-new-nvptx-sm_35.bc b/clang/test/Driver/Inputs/libomptarget/libomptarget-new-nvptx-sm_35.bc deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/clang/test/Driver/Inputs/libomptarget/libomptarget-new-nvptx-sm_35.bc +++ /dev/null @@ -1 +0,0 @@ - diff --git a/clang/test/Driver/Inputs/libomptarget/libomptarget-new-nvptx-test.bc b/clang/test/Driver/Inputs/libomptarget/libomptarget-new-nvptx-test.bc deleted file mode 100644 index 8b137891791fe9..00000000000000 --- a/clang/test/Driver/Inputs/libomptarget/libomptarget-new-nvptx-test.bc +++ /dev/null @@ -1 +0,0 @@ - diff --git a/clang/test/Driver/Inputs/openmp_static_device_link/empty.o b/clang/test/Driver/Inputs/openmp_static_device_link/empty.o deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/clang/test/Driver/Inputs/openmp_static_device_link/lib.bc b/clang/test/Driver/Inputs/openmp_static_device_link/lib.bc deleted file mode 100644 index 1a87fd836dba2c..00000000000000 Binary files a/clang/test/Driver/Inputs/openmp_static_device_link/lib.bc and /dev/null differ diff --git a/clang/test/Driver/Inputs/openmp_static_device_link/libFatArchive.a b/clang/test/Driver/Inputs/openmp_static_device_link/libFatArchive.a deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/clang/test/Driver/cl-outputs.c b/clang/test/Driver/cl-outputs.c index 07ff43642a62be..4d58f0fb548b57 100644 --- a/clang/test/Driver/cl-outputs.c +++ b/clang/test/Driver/cl-outputs.c @@ -301,5 +301,8 @@ // RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Foa.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH1 %s // RELATIVE_OBJPATH1: "-object-file-name=a.obj" +// RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fo:a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH1_COLON %s +// RELATIVE_OBJPATH1_COLON: "-object-file-name=a.obj" + // RUN: %clang_cl -fdebug-compilation-dir=. /Z7 /Fofoo/a.obj -### -- %s 2>&1 | FileCheck -check-prefix=RELATIVE_OBJPATH2 %s // RELATIVE_OBJPATH2: "-object-file-name=foo\\a.obj" diff --git a/clang/test/Driver/compiler-rt-unwind.c b/clang/test/Driver/compiler-rt-unwind.c index 4260dab9302c78..7f4e3f22ab19ae 100644 --- a/clang/test/Driver/compiler-rt-unwind.c +++ b/clang/test/Driver/compiler-rt-unwind.c @@ -3,7 +3,7 @@ // // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=platform \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-GCC %s // RTLIB-GCC: "-lgcc" // RTLIB-GCC-SAME: "--as-needed" @@ -12,7 +12,7 @@ // // RUN: %clangxx -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=platform \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-GXX %s // RTLIB-GXX: "-lgcc" // RTLIB-GXX-NOT: "--as-needed" @@ -21,11 +21,11 @@ // // RUN: not %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER-RT %s // RUN: not %clangxx -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER-RT %s // RTLIB-GCC-UNWINDLIB-COMPILER-RT: "-lgcc" // RTLIB-GCC-UNWINDLIB-COMPILER-RT-SAME: "--as-needed" @@ -35,7 +35,7 @@ // RUN: not %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \ // RUN: -shared-libgcc \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-GCC-SHARED-UNWINDLIB-COMPILER-RT %s // RTLIB-GCC-SHARED-UNWINDLIB-COMPILER-RT: "-l:libunwind.so" // RTLIB-GCC-SHARED-UNWINDLIB-COMPILER-RT-SAME: "-lgcc" @@ -43,24 +43,24 @@ // RUN: not %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \ // RUN: -static-libgcc \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-GCC-STATIC-UNWINDLIB-COMPILER-RT %s // RTLIB-GCC-STATIC-UNWINDLIB-COMPILER-RT: "-lgcc" // RTLIB-GCC-STATIC-UNWINDLIB-COMPILER-RT-SAME: "-l:libunwind.a" // // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT %s // RTLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins.a" // // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libunwind \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT %s // RUN: %clangxx -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libunwind \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT %s // RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins.a" // RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT-SAME: "--as-needed" @@ -69,21 +69,21 @@ // // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC %s // RTLIB-COMPILER-RT-UNWINDLIB-GCC: "{{.*}}libclang_rt.builtins.a" // RTLIB-COMPILER-RT-UNWINDLIB-GCC-SAME: "-lgcc_s" // // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=compiler-rt --unwindlib=libgcc \ -// RUN: -static --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -static -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC %s // RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC: "{{.*}}libclang_rt.builtins.a" // RTLIB-COMPILER-RT-UNWINDLIB-GCC-STATIC-SAME: "-lgcc_eh" // // RUN: not %clang %s 2> %t.err \ // RUN: --target=x86_64-unknown-linux -rtlib=libgcc --unwindlib=libunwind \ -// RUN: --gcc-toolchain="" -resource-dir=%S/Inputs/resource_dir \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: FileCheck --input-file=%t.err --check-prefix=RTLIB-GCC-UNWINDLIB-COMPILER_RT %s // RTLIB-GCC-UNWINDLIB-COMPILER_RT: "{{[.|\\\n]*}}--rtlib=libgcc requires --unwindlib=libgcc" // @@ -97,7 +97,6 @@ // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-w64-mingw32 -rtlib=compiler-rt --unwindlib=libunwind \ // RUN: -shared-libgcc \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=MINGW-RTLIB-COMPILER-RT-SHARED-UNWINDLIB-COMPILER-RT %s // MINGW-RTLIB-COMPILER-RT-SHARED-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a" // MINGW-RTLIB-COMPILER-RT-SHARED-UNWINDLIB-COMPILER-RT-SAME: "-l:libunwind.dll.a" @@ -105,18 +104,15 @@ // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-w64-mingw32 -rtlib=compiler-rt --unwindlib=libunwind \ // RUN: -static-libgcc \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=MINGW-RTLIB-COMPILER-RT-STATIC-UNWINDLIB-COMPILER-RT %s // MINGW-RTLIB-COMPILER-RT-STATIC-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a" // MINGW-RTLIB-COMPILER-RT-STATIC-UNWINDLIB-COMPILER-RT-SAME: "-l:libunwind.a" // // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-w64-mingw32 -rtlib=compiler-rt --unwindlib=libunwind \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=MINGW-RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT %s // RUN: %clangxx -### %s 2>&1 \ // RUN: --target=x86_64-w64-mingw32 -rtlib=compiler-rt --unwindlib=libunwind \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=MINGW-RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT %s // MINGW-RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT: "{{.*}}libclang_rt.builtins-x86_64.a" // MINGW-RTLIB-COMPILER-RT-UNWINDLIB-COMPILER-RT-SAME: "-lunwind" diff --git a/clang/test/Driver/constructors.c b/clang/test/Driver/constructors.c index 1cb3aec840c2d9..570b6ec94617f2 100644 --- a/clang/test/Driver/constructors.c +++ b/clang/test/Driver/constructors.c @@ -7,58 +7,49 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/resource_dir \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/fake_install_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: -fno-use-init-array \ // RUN: --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/fake_install_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-NO-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: -fno-use-init-array -fuse-init-array \ // RUN: --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/fake_install_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: -fuse-init-array \ // RUN: --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=arm-unknown-linux-androideabi \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=i386-unknown-linux-android \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=aarch64-none-linux-gnu \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ @@ -68,7 +59,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=arm64-none-linux-gnu \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s // // RUN: %clang -### %s -fsyntax-only 2>&1 \ diff --git a/clang/test/Driver/cuda-detect.cu b/clang/test/Driver/cuda-detect.cu index 49e58004e672c3..67af470018ff96 100644 --- a/clang/test/Driver/cuda-detect.cu +++ b/clang/test/Driver/cuda-detect.cu @@ -146,8 +146,8 @@ // Verify that C++ include paths are passed for both host and device frontends. // RUN: %clang -### --target=x86_64-linux-gnu %s \ -// RUN: --stdlib=libstdc++ --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree2 \ -// RUN: -nogpulib -nogpuinc --gcc-toolchain="" 2>&1 \ +// RUN: --stdlib=libstdc++ --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree2 \ +// RUN: -nogpulib -nogpuinc 2>&1 \ // RUN: | FileCheck %s --check-prefix CHECK-CXXINCLUDE // Verify that CUDA SDK version is propagated to the CC1 compilations. diff --git a/clang/test/Driver/darwin-ld-reexports.c b/clang/test/Driver/darwin-ld-reexports.c new file mode 100644 index 00000000000000..2e96db49a8a387 --- /dev/null +++ b/clang/test/Driver/darwin-ld-reexports.c @@ -0,0 +1,21 @@ +// RUN: touch %t.o +// RUN: %clang -target arm64-apple-darwin13 -### \ +// RUN: -reexport_framework Foo -reexport-lBar -reexport_library Baz %t.o 2> %t.log + +// Check older spellings also work. +// RUN: %clang -target arm64-apple-darwin13 -### \ +// RUN: -Xlinker -reexport_framework -Xlinker Forest \ +// RUN: -Xlinker -reexport-lBranch \ +// RUN: -Xlinker -reexport_library -Xlinker Flower %t.o 2>> %t.log +// RUN: FileCheck -check-prefix=LINK_REEXPORT %s < %t.log + +// LINK_REEXPORT: {{ld(.exe)?"}} +// LINK_REEXPORT: "-reexport_framework" "Foo" +// LINK_REEXPORT: "-reexport-lBar" +// LINK_REEXPORT: "-reexport_library" "Baz" +// LINK_REEXPORT: "-reexport_framework" "Forest" +// LINK_REEXPORT: "-reexport-lBranch" +// LINK_REEXPORT: "-reexport_library" "Flower" + +// Make sure arguments are not repeated. +// LINK_REEXPORT-NOT: "-reexport diff --git a/clang/test/Driver/dragonfly.c b/clang/test/Driver/dragonfly.c index 931f23f6f57b5f..33c4e4c77eac5e 100644 --- a/clang/test/Driver/dragonfly.c +++ b/clang/test/Driver/dragonfly.c @@ -5,7 +5,6 @@ // Check x86_64-unknown-dragonfly, X86_64 // RUN: %clang -### %s 2>&1 --target=x86_64-unknown-dragonfly \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_dragonfly_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-X86_64 %s // CHECK-LD-X86_64: "-cc1" "-triple" "x86_64-unknown-dragonfly" diff --git a/clang/test/Driver/env.c b/clang/test/Driver/env.c index 40a42dc9618576..3f56c7fdae9022 100644 --- a/clang/test/Driver/env.c +++ b/clang/test/Driver/env.c @@ -8,13 +8,13 @@ // RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: --rtlib=platform --unwindlib=platform -no-pie \ -// RUN: --gcc-toolchain="" 2>&1 | FileCheck --check-prefix=CHECK-LD-32 %s +// RUN: 2>&1 | FileCheck --check-prefix=CHECK-LD-32 %s // // RUN: env -i LC_ALL=C PATH="" LD_LIBRARY_PATH="$LD_LIBRARY_PATH" CLANG_NO_DEFAULT_CONFIG=1 \ // RUN: %clang %s -### -o %t.o --target=i386-unknown-linux \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: --rtlib=platform --unwindlib=platform -no-pie \ -// RUN: --gcc-toolchain="" 2>&1 | FileCheck --check-prefix=CHECK-LD-32 %s +// RUN: 2>&1 | FileCheck --check-prefix=CHECK-LD-32 %s // // CHECK-LD-32-NOT: warning: // CHECK-LD-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" diff --git a/clang/test/Driver/haiku.c b/clang/test/Driver/haiku.c index 060a56b3c70e56..3f421ab6e81e68 100644 --- a/clang/test/Driver/haiku.c +++ b/clang/test/Driver/haiku.c @@ -39,7 +39,6 @@ // Check x86_64-unknown-haiku, X86_64 // RUN: %clang -### %s 2>&1 --target=x86_64-unknown-haiku \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/haiku_x86_64_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-X86_64 %s // CHECK-LD-X86_64: "-cc1" "-triple" "x86_64-unknown-haiku" @@ -63,7 +62,6 @@ // Check the right flags are present with -shared // RUN: %clang -### %s -shared 2>&1 --target=x86_64-unknown-haiku \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/haiku_x86_64_tree \ // RUN: | FileCheck --check-prefix=CHECK-X86_64-SHARED %s // CHECK-X86_64-SHARED: "-cc1" "-triple" "x86_64-unknown-haiku" diff --git a/clang/test/Driver/hexagon-toolchain-elf.c b/clang/test/Driver/hexagon-toolchain-elf.c index da859a144cfc88..ac921547266c95 100644 --- a/clang/test/Driver/hexagon-toolchain-elf.c +++ b/clang/test/Driver/hexagon-toolchain-elf.c @@ -36,7 +36,6 @@ // RUN: %clangxx -### --target=hexagon-unknown-elf -fno-integrated-as \ // RUN: -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \ -// RUN: --gcc-toolchain="" \ // RUN: -nostdlibinc %s 2>&1 | FileCheck -check-prefix=CHECK113 %s // CHECK113: "-cc1" // CHECK113-NOT: "-internal-isystem" diff --git a/clang/test/Driver/hip-link-shared-library.hip b/clang/test/Driver/hip-link-shared-library.hip index 73643682dda8ae..a075ee82dda1cb 100644 --- a/clang/test/Driver/hip-link-shared-library.hip +++ b/clang/test/Driver/hip-link-shared-library.hip @@ -1,6 +1,7 @@ // RUN: touch %t.o +// RUN: touch %t.so // RUN: %clang --hip-link -ccc-print-bindings --target=x86_64-linux-gnu \ -// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o %S/Inputs/in.so \ +// RUN: --cuda-gpu-arch=gfx803 --cuda-gpu-arch=gfx900 %t.o %t.so \ // RUN: --no-offload-new-driver -fgpu-rdc 2>&1 | FileCheck %s // CHECK: # "x86_64-unknown-linux-gnu" - "offload bundler", inputs: ["[[IN:.*o]]"], outputs: ["[[HOSTOBJ:.*o]]", "{{.*o}}", "{{.*o}}"] @@ -11,4 +12,4 @@ // CHECK-NOT: offload bundler // CHECK: # "amdgcn-amd-amdhsa" - "AMDGCN::Linker", inputs: ["[[IMG1]]", "[[IMG2]]"], output: "[[FATBINOBJ:.*o]]" // CHECK-NOT: offload bundler -// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[HOSTOBJ]]", "{{.*}}/Inputs/in.so", "[[FATBINOBJ]]"], output: "a.out" +// CHECK: # "x86_64-unknown-linux-gnu" - "GNU::Linker", inputs: ["[[HOSTOBJ]]", "{{.*}}.so", "[[FATBINOBJ]]"], output: "a.out" diff --git a/clang/test/Driver/linux-header-search.cpp b/clang/test/Driver/linux-header-search.cpp index dd4d6eb483a3fb..70a85deac89e40 100644 --- a/clang/test/Driver/linux-header-search.cpp +++ b/clang/test/Driver/linux-header-search.cpp @@ -9,7 +9,6 @@ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-SYSROOT %s // CHECK-BASIC-LIBCXX-SYSROOT: "-cc1" // CHECK-BASIC-LIBCXX-SYSROOT: "-isysroot" "[[SYSROOT:[^"]+]]" @@ -24,7 +23,6 @@ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree/ \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-SYSROOT-SLASH %s // CHECK-BASIC-LIBCXX-SYSROOT-SLASH: "-cc1" // CHECK-BASIC-LIBCXX-SYSROOT-SLASH-SAME: "-isysroot" "[[SYSROOT:[^"]+/]]" @@ -38,7 +36,6 @@ // RUN: -ccc-install-dir %S/Inputs/basic_linux_libcxx_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-INSTALL %s // CHECK-BASIC-LIBCXX-INSTALL: "-cc1" // CHECK-BASIC-LIBCXX-INSTALL: "-isysroot" "[[SYSROOT:[^"]+]]" @@ -52,7 +49,6 @@ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_libcxxv2_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXXV2-SYSROOT %s // CHECK-BASIC-LIBCXXV2-SYSROOT: "-cc1" // CHECK-BASIC-LIBCXXV2-SYSROOT: "-isysroot" "[[SYSROOT:[^"]+]]" @@ -65,7 +61,6 @@ // RUN: -ccc-install-dir %S/Inputs/basic_linux_libcxxv2_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_libcxxv2_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXXV2-INSTALL %s // CHECK-BASIC-LIBCXXV2-INSTALL: "-cc1" // CHECK-BASIC-LIBCXXV2-INSTALL: "-isysroot" "[[SYSROOT:[^"]+]]" @@ -80,7 +75,6 @@ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_libstdcxx_tree/ \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBSTDCXX-SYSROOT-SLASH %s // CHECK-BASIC-LIBSTDCXX-SYSROOT-SLASH: "-cc1" // CHECK-BASIC-LIBSTDCXX-SYSROOT-SLASH-SAME: "-isysroot" "[[SYSROOT:[^"]+/]]" @@ -93,7 +87,6 @@ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_libstdcxx_libcxxv2_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT %s // CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "-cc1" // CHECK-BASIC-LIBSTDCXX-LIBCXXV2-SYSROOT: "-isysroot" "[[SYSROOT:[^"]+]]" @@ -106,7 +99,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnu -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_4.6.2_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-GENTOO-4-6-2 %s // CHECK-GENTOO-4-6-2: "-cc1" // CHECK-GENTOO-4-6-2: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -121,7 +113,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnu -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_4.6.4_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-GENTOO-4-6-4 %s // CHECK-GENTOO-4-6-4: "-cc1" // CHECK-GENTOO-4-6-4: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -136,7 +127,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnu -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_4.9.3_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-GENTOO-4-9-3 %s // CHECK-GENTOO-4-9-3: "-cc1" // CHECK-GENTOO-4-9-3: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -155,14 +145,12 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnu -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-GENTOO-4-9-3 %s // // Test that gcc-config support does not break multilib. // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnux32 -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-GENTOO-4-9-3-X32 %s // CHECK-GENTOO-4-9-3-X32: "-cc1" // CHECK-GENTOO-4-9-3-X32: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -178,7 +166,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=i386-unknown-linux-gnu -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-GENTOO-4-9-3-32 %s // CHECK-GENTOO-4-9-3-32: "-cc1" // CHECK-GENTOO-4-9-3-32: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -198,7 +185,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnu -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_4.9.x_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-GENTOO-4-9-X %s // // CHECK-GENTOO-4-9-X: "-cc1" @@ -215,7 +201,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnux32 -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_4.9.x_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-GENTOO-4-9-X-X32 %s // CHECK-GENTOO-4-9-X-X32: "-cc1" // CHECK-GENTOO-4-9-X-X32: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -231,7 +216,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=i386-unknown-linux-gnu -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_4.9.x_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-GENTOO-4-9-X-32 %s // CHECK-GENTOO-4-9-X-32: "-cc1" // CHECK-GENTOO-4-9-X-32: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -248,14 +232,12 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=loongarch64-unknown-linux-gnu -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/debian_loong64_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-LOONG64-GNU %s // // Check that "-gnuf64" is seen as "-gnu" for loong64. // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=loongarch64-unknown-linux-gnuf64 -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/debian_loong64_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-LOONG64-GNU %s // CHECK-LOONG64-GNU: "-cc1" // CHECK-LOONG64-GNU: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -274,7 +256,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=mips64-unknown-linux-gnuabi64 -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-MIPS64-GNUABI %s // CHECK-MIPS64-GNUABI: "-cc1" // CHECK-MIPS64-GNUABI: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -292,7 +273,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=mips64el-unknown-linux-gnuabi64 -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-MIPS64EL-GNUABI %s // CHECK-MIPS64EL-GNUABI: "-cc1" // CHECK-MIPS64EL-GNUABI: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -311,7 +291,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=arm-oe-linux-gnueabi -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/openembedded_arm_linux_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-OE-ARM %s // CHECK-OE-ARM: "-cc1" @@ -323,7 +302,6 @@ // RUN: %clang -### %s -fsyntax-only 2>&1 \ // RUN: --target=aarch64-oe-linux -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/openembedded_aarch64_linux_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-OE-AARCH64 %s // CHECK-OE-AARCH64: "-cc1" diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c index d77367b4ece7b9..4020b138dc8fde 100644 --- a/clang/test/Driver/linux-ld.c +++ b/clang/test/Driver/linux-ld.c @@ -4,7 +4,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i386-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-32 %s // CHECK-LD-32-NOT: warning: @@ -17,7 +16,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-64 %s // CHECK-LD-64-NOT: warning: @@ -36,7 +34,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-X32 %s // CHECK-LD-X32-NOT: warning: @@ -51,7 +48,6 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux \ // RUN: -resource-dir=%S/Inputs/resource_dir \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: --rtlib=compiler-rt \ // RUN: | FileCheck --check-prefix=CHECK-LD-RT %s @@ -74,7 +70,6 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i686-unknown-linux \ // RUN: -resource-dir=%S/Inputs/resource_dir \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: --rtlib=compiler-rt \ // RUN: | FileCheck --check-prefix=CHECK-LD-RT-I686 %s @@ -96,7 +91,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-androideabi \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: --rtlib=compiler-rt \ // RUN: | FileCheck --check-prefix=CHECK-LD-RT-ANDROID %s @@ -111,7 +105,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-GCC %s // CHECK-LD-GCC-NOT: warning: @@ -131,7 +124,6 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ // RUN: -static-libgcc \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-64-STATIC-LIBGCC %s // CHECK-LD-64-STATIC-LIBGCC-NOT: warning: @@ -150,7 +142,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-NO-LIBGCC %s // CHECK-CLANG-NO-LIBGCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -160,7 +151,6 @@ // // RUN: %clangxx -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANGXX-NO-LIBGCC %s // CHECK-CLANGXX-NO-LIBGCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -170,7 +160,6 @@ // // RUN: %clang -static -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-NO-LIBGCC-STATIC %s // CHECK-CLANG-NO-LIBGCC-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -178,7 +167,6 @@ // // RUN: %clang -static-pie -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-LD-STATIC-PIE %s // CHECK-CLANG-LD-STATIC-PIE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -189,7 +177,6 @@ // // RUN: not %clang -static-pie -pie -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-LD-STATIC-PIE-PIE %s // CHECK-CLANG-LD-STATIC-PIE-PIE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -200,7 +187,6 @@ // // RUN: not %clang -static-pie -static -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-LD-STATIC-PIE-STATIC %s // CHECK-CLANG-LD-STATIC-PIE-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -211,14 +197,12 @@ // // RUN: not %clang -static-pie -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-LD-STATIC-PIE-NOPIE %s // CHECK-CLANG-LD-STATIC-PIE-NOPIE: error: cannot specify 'nopie' along with 'static-pie' // // RUN: %clang -dynamic -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-NO-LIBGCC-DYNAMIC %s // CHECK-CLANG-NO-LIBGCC-DYNAMIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -228,7 +212,6 @@ // // RUN: %clang -static-libgcc -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-STATIC-LIBGCC %s // CHECK-CLANG-STATIC-LIBGCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -238,7 +221,6 @@ // // RUN: %clang -static-libgcc -dynamic -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-STATIC-LIBGCC-DYNAMIC %s // CHECK-CLANG-STATIC-LIBGCC-DYNAMIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -248,7 +230,6 @@ // // RUN: %clang -shared-libgcc -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-SHARED-LIBGCC %s // CHECK-CLANG-SHARED-LIBGCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -258,7 +239,6 @@ // // RUN: %clang -shared-libgcc -dynamic -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-SHARED-LIBGCC-DYNAMIC %s // CHECK-CLANG-SHARED-LIBGCC-DYNAMIC: "-lgcc_s" "-lgcc" @@ -267,7 +247,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-ANDROID-NONE %s // CHECK-CLANG-ANDROID-NONE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -275,7 +254,6 @@ // // RUN: %clang -shared -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-ANDROID-SHARED %s // CHECK-CLANG-ANDROID-SHARED: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -283,7 +261,6 @@ // // RUN: %clang -static -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-CLANG-ANDROID-STATIC %s // CHECK-CLANG-ANDROID-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -292,7 +269,6 @@ // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ // RUN: -static \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-64-STATIC %s // CHECK-LD-64-STATIC-NOT: warning: @@ -309,7 +285,7 @@ // CHECK-LD-64-STATIC: "--start-group" "-lgcc" "-lgcc_eh" "-lc" "--end-group" // RUN: %clang -no-pie -### %s --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform -shared -static \ -// RUN: --gcc-toolchain= --sysroot=%S/Inputs/basic_linux_tree 2>&1 | FileCheck --check-prefix=CHECK-LD-SHARED-STATIC %s +// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 | FileCheck --check-prefix=CHECK-LD-SHARED-STATIC %s // CHECK-LD-SHARED-STATIC: "-shared" "-static" // CHECK-LD-SHARED-STATIC: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtbeginS.o" // CHECK-LD-SHARED-STATIC: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtendS.o" @@ -318,13 +294,11 @@ // RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \ // RUN: -static-libgcc -static \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-64-STATIC %s // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i386-unknown-linux -rtlib=platform --unwindlib=platform -m32 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/multilib_32bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-32-TO-32 %s // CHECK-32-TO-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -340,7 +314,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i386-unknown-linux -rtlib=platform --unwindlib=platform -m64 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/multilib_32bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-32-TO-64 %s // CHECK-32-TO-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -356,7 +329,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform -m64 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-64-TO-64 %s // CHECK-64-TO-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -372,7 +344,6 @@ // // RUN: not %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=plaform --unwindlib=platform -m32 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-64-TO-32 %s // CHECK-64-TO-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -388,7 +359,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-X32 %s // CHECK-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -404,7 +374,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform -mx32 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-64-TO-X32 %s // CHECK-64-TO-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -420,7 +389,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i386-unknown-linux -rtlib=platform --unwindlib=platform -mx32 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-32-TO-X32 %s // CHECK-32-TO-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -436,7 +404,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform --unwindlib=platform -m64 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-X32-TO-64 %s // CHECK-X32-TO-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -452,7 +419,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform --unwindlib=platform -m32 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/multilib_64bit_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-X32-TO-32 %s // CHECK-X32-TO-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -484,7 +450,6 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i386-unknown-linux -rtlib=platform --unwindlib=platform -m32 \ // RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing1/bin \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-GCC-VERSION1 %s // CHECK-GCC-VERSION1: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -496,7 +461,6 @@ // RUN: --target=x86_64-unknown-linux-gnu \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ -// RUN: --gcc-toolchain="" \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-SYSROOT %s @@ -509,7 +473,6 @@ // RUN: --target=x86_64-unknown-linux-gnu \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_linux_libcxx_tree/usr/bin \ -// RUN: --gcc-toolchain="" \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-INSTALL %s @@ -525,7 +488,6 @@ // RUN: --target=x86_64-unknown-linux-gnu \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_linux_libcxx_tree/usr/bin \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-C-LINK %s // CHECK-BASIC-LIBCXX-C-LINK-NOT: warning: @@ -538,7 +500,6 @@ // Check multi arch support on Ubuntu 12.04 LTS. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-unknown-linux-gnueabihf -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBUNTU-12-04-ARM-HF %s // @@ -547,7 +508,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-unknown-linux-musleabihf -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBUNTU-12-04-ARM-HF %s // CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -563,7 +523,6 @@ // Check Ubuntu 13.10 on x86-64 targeting arm-linux-gnueabihf. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-gnueabihf -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/x86-64_ubuntu_13.10 \ // RUN: | FileCheck --check-prefix=CHECK-X86-64-UBUNTU-13-10-ARM-HF %s // CHECK-X86-64-UBUNTU-13-10-ARM-HF: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -582,7 +541,6 @@ // Check Ubuntu 13.10 on x86-64 targeting arm-linux-gnueabi. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-gnueabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/x86-64_ubuntu_13.10 \ // RUN: | FileCheck --check-prefix=CHECK-X86-64-UBUNTU-13-10-ARM %s // CHECK-X86-64-UBUNTU-13-10-ARM: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -601,7 +559,6 @@ // Check Ubuntu 14.04 on powerpc64le. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=powerpc64le-unknown-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-PPC64LE %s // CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -618,7 +575,6 @@ // "/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32/crtn.o" // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBUNTU-14-04-X32 %s // CHECK-UBUNTU-14-04-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -635,7 +591,6 @@ // Check fedora 18 on arm. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armv7-unknown-linux-gnueabihf -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/fedora_18_tree \ // RUN: | FileCheck --check-prefix=CHECK-FEDORA-18-ARM-HF %s // CHECK-FEDORA-18-ARM-HF: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -650,12 +605,10 @@ // Check Fedora 21 on AArch64. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm64-unknown-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/fedora_21_tree \ // RUN: | FileCheck --check-prefix=CHECK-FEDORA-21-AARCH64 %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-unknown-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/fedora_21_tree \ // RUN: | FileCheck --check-prefix=CHECK-FEDORA-21-AARCH64 %s // CHECK-FEDORA-21-AARCH64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -670,7 +623,6 @@ // Check Fedora 31 on riscv64. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=riscv64-redhat-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/fedora_31_riscv64_tree \ // RUN: | FileCheck --check-prefix=CHECK-FEDORA-31-RISCV64 %s // CHECK-FEDORA-31-RISCV64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -684,7 +636,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-unknown-linux-gnueabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBUNTU-12-04-ARM %s // CHECK-UBUNTU-12-04-ARM: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -700,7 +651,6 @@ // Test the setup that shipped in SUSE 10.3 on ppc64. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=powerpc64-suse-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/suse_10.3_ppc64_tree \ // RUN: | FileCheck --check-prefix=CHECK-SUSE-10-3-PPC64 %s // CHECK-SUSE-10-3-PPC64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -713,12 +663,10 @@ // Check openSuse Leap 42.2 on AArch64 // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm64-unknown-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/opensuse_42.2_aarch64_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-42-2-AARCH64 %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-unknown-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/opensuse_42.2_aarch64_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-42-2-AARCH64 %s // CHECK-OPENSUSE-42-2-AARCH64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -733,12 +681,10 @@ // Check openSUSE Tumbleweed on armv6hl // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armv6hl-suse-linux-gnueabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_armv6hl_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-ARMV6HL %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armv6hl-suse-linux-gnueabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_armv6hl_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-ARMV6HL %s // CHECK-OPENSUSE-TW-ARMV6HL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -753,12 +699,10 @@ // Check openSUSE Tumbleweed on armv7hl // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armv7hl-suse-linux-gnueabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_armv7hl_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-ARMV7HL %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armv7hl-suse-linux-gnueabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_armv7hl_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-ARMV7HL %s // CHECK-OPENSUSE-TW-ARMV7HL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -773,12 +717,10 @@ // Check openSUSE Tumbleweed on riscv64 // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=riscv64-suse-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_riscv64_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-RISCV64 %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=riscv64-suse-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_riscv64_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-RISCV64 %s // CHECK-OPENSUSE-TW-RISCV64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -793,7 +735,6 @@ // Check openSUSE Tumbleweed on ppc // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=powerpc-unknown-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/opensuse_tumbleweed_ppc_tree \ // RUN: | FileCheck --check-prefix=CHECK-OPENSUSE-TW-PPC %s // CHECK-OPENSUSE-TW-PPC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1048,32 +989,26 @@ // Test linker invocation on Android. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-androideabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i686-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID %s // CHECK-ANDROID: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1090,19 +1025,16 @@ // CHECK-ANDROID: "{{.*}}{{/|\\\\}}crtend_android.o" // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-androideabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-SO %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-SO %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-SO %s @@ -1113,13 +1045,11 @@ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-SO %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i686-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-SO %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-SO %s @@ -1136,7 +1066,6 @@ // CHECK-ANDROID-SO: "{{.*}}{{/|\\\\}}crtend_so.o" // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-androideabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -static \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s @@ -1147,7 +1076,6 @@ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -static \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s @@ -1158,13 +1086,11 @@ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i686-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -static \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -static \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s @@ -1180,37 +1106,31 @@ // CHECK-ANDROID-STATIC: "{{.*}}{{/|\\\\}}crtend_android.o" // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-androideabi -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -pie \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PIE %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -pie \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PIE %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -pie \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PIE %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -pie \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PIE %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i686-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -pie \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PIE %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -pie \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PIE %s @@ -1225,32 +1145,26 @@ // CHECK-ANDROID-PIE: "{{.*}}{{/|\\\\}}crtend_android.o" // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-androideabi \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-32 %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-android \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-32 %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-64 %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm64-linux-android \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-64 %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i686-linux-android \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-32 %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-linux-android \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-64 %s // CHECK-ANDROID-32: "-dynamic-linker" "/system/bin/linker" @@ -1260,13 +1174,11 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: -fsanitize=hwaddress \ // RUN: --target=x86_64-linux-android33 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-OLD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: -fsanitize=hwaddress \ // RUN: --target=x86_64-linux-android34 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-NEW %s // CHECK-ANDROID-OLD: "-dynamic-linker" "/system/bin/linker64" @@ -1275,67 +1187,55 @@ // Test that -pthread does not add -lpthread on Android. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-androideabi -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm64-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i686-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-androideabi -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm64-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i686-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-linux-android -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s @@ -1343,20 +1243,19 @@ // // RUN: not %clang %t.o -no-pie -### -o %t 2>&1 \ // RUN: --target=arm-linux-androideabi -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD-LINK %s // CHECK-ANDROID-PTHREAD-LINK-NOT: argument unused during compilation: '-pthread' /// Check -fandroid-pad-segment. // RUN: %clang -### %s --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/basic_android_tree/sysroot \ +// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -fandroid-pad-segment 2>&1 | FileCheck --check-prefix=CHECK-ANDROID-PAD-PHDR %s // CHECK-ANDROID-PAD-PHDR: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-ANDROID-PAD-PHDR: "[[SYSROOT]]/usr/lib/crtbegin_dynamic.o" "[[SYSROOT]]/usr/lib/crt_pad_segment.o" // RUN: %clang -### %s --target=aarch64-linux-android -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/basic_android_tree/sysroot \ +// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ // RUN: -fandroid-pad-segment -fno-android-pad-segment 2>&1 | FileCheck --check-prefix=CHECK-NO-ANDROID-PAD-PHDR %s // CHECK-NO-ANDROID-PAD-PHDR: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-NO-ANDROID-PAD-PHDR: "[[SYSROOT]]/usr/lib/crtbegin_dynamic.o" @@ -1368,14 +1267,12 @@ // Check linker invocation on a Debian LoongArch sysroot. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=loongarch64-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_loong64_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-LOONG64 %s // // Check that "-gnuf64" is seen as "-gnu" for loong64. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=loongarch64-linux-gnuf64 -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_loong64_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-LOONG64 %s // CHECK-DEBIAN-ML-LOONG64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1391,7 +1288,6 @@ // Check linker invocation on Debian 6 MIPS 32/64-bit. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=mipsel-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPSEL %s // CHECK-DEBIAN-ML-MIPSEL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1407,7 +1303,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=mips64el-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL %s // CHECK-DEBIAN-ML-MIPS64EL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1423,7 +1318,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=mips64el-linux-gnu -rtlib=platform --unwindlib=platform -mabi=n32 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-N32 %s // CHECK-DEBIAN-ML-MIPS64EL-N32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1439,7 +1333,6 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=mips64el-linux-gnuabi64 -rtlib=platform --unwindlib=platform -mabi=32 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-O32 %s // CHECK-DEBIAN-ML-MIPS64EL-O32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1455,12 +1348,10 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=mips64-unknown-linux-gnu --rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64-GNUABI %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=mips64-linux-gnuabi64 -rtlib=platform --unwindlib=platform -mabi=n64 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64-GNUABI %s // CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1477,12 +1368,10 @@ // // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=mips64el-unknown-linux-gnu -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-GNUABI %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=mips64el-linux-gnuabi64 -rtlib=platform --unwindlib=platform -mabi=n64 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/debian_6_mips64_tree \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-GNUABI %s // CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1500,7 +1389,6 @@ // Test linker invocation for Freescale SDK (OpenEmbedded). // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=powerpc-fsl-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/freescale_ppc_tree \ // RUN: | FileCheck --check-prefix=CHECK-FSL-PPC %s // CHECK-FSL-PPC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1510,7 +1398,6 @@ // CHECK-FSL-PPC: "-L[[SYSROOT]]/usr/lib" // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=powerpc64-fsl-linux -rtlib=platform --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/freescale_ppc64_tree \ // RUN: | FileCheck --check-prefix=CHECK-FSL-PPC64 %s // CHECK-FSL-PPC64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1520,53 +1407,41 @@ // // Check that crtfastmath.o is linked with -ffast-math and with -Ofast. // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -funsafe-math-optimizations\ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -Ofast\ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -Ofast -O3\ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -O3 -Ofast\ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -ffast-math -fno-fast-math \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -Ofast -fno-fast-math \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -Ofast -fno-unsafe-math-optimizations \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -fno-fast-math -Ofast \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // RUN: %clang --target=x86_64-unknown-linux -no-pie -### %s -fno-unsafe-math-optimizations -Ofast \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH %s // We don't have crtfastmath.o in the i386 tree, use it to check that file // detection works. // RUN: %clang --target=i386-unknown-linux -no-pie -### %s -ffast-math \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s // CHECK-CRTFASTMATH: usr/lib/gcc/x86_64-unknown-linux/10.2.0{{/|\\\\}}crtfastmath.o @@ -1574,21 +1449,18 @@ // Check that we link in gcrt1.o when compiling with -pg // RUN: %clang -pg --target=x86_64-unknown-linux -no-pie -### %s \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>& 1 \ // RUN: | FileCheck --check-prefix=CHECK-PG %s // CHECK-PG: gcrt1.o // GCC forwards -u to the linker. // RUN: %clang -u asdf --target=x86_64-unknown-linux -no-pie -### %s \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>& 1 \ // RUN: | FileCheck --check-prefix=CHECK-u %s // CHECK-u: "-u" "asdf" // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armeb-unknown-linux \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ARMEB %s // CHECK-ARMEB: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1598,7 +1470,6 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armebv7-unknown-linux \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7EB %s // CHECK-ARMV7EB: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1609,20 +1480,17 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armv7-unknown-linux \ // RUN: -mbig-endian \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7EB %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armebv7-unknown-linux \ // RUN: -mbig-endian \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7EB %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armv7-unknown-linux \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7EL %s // CHECK-ARMV7EL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1633,20 +1501,17 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armebv7-unknown-linux \ // RUN: -mlittle-endian \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7EL %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=armv7-unknown-linux \ // RUN: -mlittle-endian \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ARMV7EL %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64_be-unknown-linux \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-AARCH64BE %s // CHECK-AARCH64BE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1657,20 +1522,17 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-unknown-linux \ // RUN: -mbig-endian \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-AARCH64BE %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64_be-unknown-linux \ // RUN: -mbig-endian \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-AARCH64BE %s // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-unknown-linux \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-AARCH64LE %s // CHECK-AARCH64LE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1681,7 +1543,6 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64_be-unknown-linux \ // RUN: -mlittle-endian \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-AARCH64LE %s @@ -1775,7 +1636,6 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnu -rtlib=platform --unwindlib=platform \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-LD-GENTOO %s // CHECK-LD-GENTOO-NOT: warning: // CHECK-LD-GENTOO: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1791,7 +1651,6 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=i686-unknown-linux-gnu -rtlib=platform --unwindlib=platform \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-LD-GENTOO-32 %s // CHECK-LD-GENTOO-32-NOT: warning: // CHECK-LD-GENTOO-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1807,7 +1666,6 @@ // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform --unwindlib=platform \ // RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-LD-GENTOO-X32 %s // CHECK-LD-GENTOO-X32-NOT: warning: // CHECK-LD-GENTOO-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" @@ -1833,7 +1691,6 @@ // Check whether gcc7 install works fine on Amazon Linux AMI // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=x86_64-amazon-linux -rtlib=libgcc --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/ami_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-AMI %s // CHECK-LD-AMI-NOT: warning: @@ -1853,7 +1710,6 @@ // Check whether the OpenEmbedded ARM libs are added correctly. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=arm-oe-linux-gnueabi -rtlib=libgcc --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/openembedded_arm_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-OE-ARM %s @@ -1872,7 +1728,6 @@ // Check whether the OpenEmbedded AArch64 libs are added correctly. // RUN: %clang -### %s -no-pie 2>&1 \ // RUN: --target=aarch64-oe-linux -rtlib=libgcc --unwindlib=platform \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/openembedded_aarch64_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-OE-AARCH64 %s diff --git a/clang/test/Driver/linux-musl-header-search.cpp b/clang/test/Driver/linux-musl-header-search.cpp index c6d958583d0158..acff5b71aa65a8 100644 --- a/clang/test/Driver/linux-musl-header-search.cpp +++ b/clang/test/Driver/linux-musl-header-search.cpp @@ -2,7 +2,7 @@ // RUN: --target=x86_64-linux-musl -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ -// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree --gcc-toolchain= \ +// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ // RUN: | FileCheck --check-prefix=CHECK-X86-64-LIBCXX %s // RESOURCE_DIR/include comes after /usr/include on linux-musl. @@ -18,7 +18,7 @@ // RUN: --target=x86_64-linux-musl \ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ -// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree --gcc-toolchain= \ +// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ // RUN: | FileCheck --check-prefix=CHECK-NOBUILTININC %s // CHECK-NOBUILTININC: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" @@ -28,7 +28,7 @@ // RUN: --target=x86_64-linux-musl \ // RUN: -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ -// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree --gcc-toolchain= \ +// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ // RUN: | FileCheck --check-prefix=CHECK-NOSTDLIBINC %s // CHECK-NOSTDLIBINC: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" diff --git a/clang/test/Driver/linux-per-target-runtime-dir.c b/clang/test/Driver/linux-per-target-runtime-dir.c index 8c721d82821f6a..97e746f57eda13 100644 --- a/clang/test/Driver/linux-per-target-runtime-dir.c +++ b/clang/test/Driver/linux-per-target-runtime-dir.c @@ -3,7 +3,6 @@ // RUN: -stdlib=libc++ \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: -ccc-install-dir %S/Inputs/basic_linux_libcxx_tree/usr/bin \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \ // RUN: | FileCheck --check-prefix=CHECK-PER-TARGET-RUNTIME %s // CHECK-PER-TARGET-RUNTIME: "-cc1" diff --git a/clang/test/Driver/mips-reduced-toolchain.cpp b/clang/test/Driver/mips-reduced-toolchain.cpp index 54d269562b3a23..4c15271f7a5f55 100644 --- a/clang/test/Driver/mips-reduced-toolchain.cpp +++ b/clang/test/Driver/mips-reduced-toolchain.cpp @@ -4,7 +4,7 @@ // RUN: %clang -### %s 2>&1 \ // RUN: --target=mips-linux-gnu \ // RUN: --sysroot=%S/Inputs/debian_reduced_mips_tree \ -// RUN: --gcc-toolchain="" -no-pie \ +// RUN: -no-pie \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPS %s // CHECK-DEBIAN-MIPS: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-DEBIAN-MIPS: "{{.*}}/usr/lib/gcc/mips-linux-gnu/4.7{{/|\\\\}}crtbegin.o" @@ -16,7 +16,7 @@ // RUN: %clang -### %s 2>&1 \ // RUN: --target=mipsel-linux-gnu \ // RUN: --sysroot=%S/Inputs/debian_reduced_mips_tree \ -// RUN: --gcc-toolchain="" -no-pie \ +// RUN: -no-pie \ // RUN: | FileCheck --check-prefix=CHECK-DEBIAN-MIPSEL %s // CHECK-DEBIAN-MIPSEL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]" // CHECK-DEBIAN-MIPSEL: "{{.*}}/usr/lib/gcc/mipsel-linux-gnu/4.7{{/|\\\\}}crtbegin.o" diff --git a/clang/test/Driver/msvc-link.c b/clang/test/Driver/msvc-link.c index 64e099ea63042f..b5c32b17378522 100644 --- a/clang/test/Driver/msvc-link.c +++ b/clang/test/Driver/msvc-link.c @@ -36,3 +36,23 @@ // VFSOVERLAY: "--vfsoverlay" // VFSOVERLAY: lld-link // VFSOVERLAY: "/vfsoverlay:{{.*}}" "{{.*}}.obj" + +// RUN: %clang -target arm64ec-pc-windows-msvc -fuse-ld=link -### %s 2>&1 | FileCheck --check-prefix=ARM64EC %s +// RUN: %clang_cl -target arm64ec-pc-windows-msvc -fuse-ld=link -### -- %s 2>&1 | FileCheck --check-prefix=ARM64EC %s +// RUN: %clang_cl -arm64EC -fuse-ld=link -### -- %s 2>&1 | FileCheck --check-prefix=ARM64EC %s +// ARM64EC: "-machine:arm64ec" + +// RUN: %clang -target arm64ec-pc-windows-msvc -fuse-ld=link -marm64x -### %s 2>&1 | \ +// RUN: FileCheck --check-prefix=ARM64X %s +// RUN: %clang -target aarch64-pc-windows-msvc -fuse-ld=link -marm64x -### %s 2>&1 | \ +// RUN: FileCheck --check-prefix=ARM64X %s +// RUN: %clang_cl -marm64x -fuse-ld=link -### -- %s 2>&1 | FileCheck --check-prefix=ARM64X %s +// RUN: %clang_cl -arm64EC -marm64x -fuse-ld=link -### -- %s 2>&1 | FileCheck --check-prefix=ARM64X %s +// ARM64X: "-machine:arm64x" + +// RUN: not %clang -target x86_64-linux-gnu -marm64x -### %s 2>&1 | FileCheck --check-prefix=HYBRID-ERR %s +// HYBRID-ERR: error: unsupported option '-marm64x' for target 'x86_64-linux-gnu' + +// RUN: %clang -c -marm64x -target arm64ec-pc-windows-msvc -fuse-ld=link -### %s 2>&1 | \ +// RUN: FileCheck --check-prefix=HYBRID-WARN %s +// HYBRID-WARN: warning: argument unused during compilation: '-marm64x' [-Wunused-command-line-argument] diff --git a/clang/test/Driver/netbsd.cpp b/clang/test/Driver/netbsd.cpp index f63391580ad0ba..6b8a86d6ee532c 100644 --- a/clang/test/Driver/netbsd.cpp +++ b/clang/test/Driver/netbsd.cpp @@ -196,7 +196,6 @@ // RUN: --target=x86_64-unknown-netbsd \ // RUN: -stdlib=libstdc++ \ // RUN: --sysroot=%S/Inputs/basic_netbsd_tree/ \ -// RUN: --gcc-toolchain="" \ // RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBSTDCXX-SYSROOT-SLASH %s // CHECK-BASIC-LIBSTDCXX-SYSROOT-SLASH: "-cc1" // CHECK-BASIC-LIBSTDCXX-SYSROOT-SLASH-SAME: "-isysroot" "[[SYSROOT:[^"]+/]]" diff --git a/clang/test/Driver/ohos.c b/clang/test/Driver/ohos.c index dfb7981525fd2a..b1ce61e7227b6b 100644 --- a/clang/test/Driver/ohos.c +++ b/clang/test/Driver/ohos.c @@ -230,7 +230,6 @@ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: --target=arm64-linux-ohos -pthread \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot \ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-OHOS-PTHREAD %s diff --git a/clang/test/Driver/openmp-offload-gpu.c b/clang/test/Driver/openmp-offload-gpu.c index d705be44e595d8..d21db7019a1aa6 100644 --- a/clang/test/Driver/openmp-offload-gpu.c +++ b/clang/test/Driver/openmp-offload-gpu.c @@ -304,8 +304,7 @@ // RUN: | FileCheck %s --check-prefix=CHECK-EMIT-LLVM-IR-BC // CHECK-EMIT-LLVM-IR-BC: "-cc1"{{.*}}"-triple" "nvptx64-nvidia-cuda"{{.*}}"-emit-llvm-bc" -// RUN: %clang -### -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -Xopenmp-target=nvptx64-nvida-cuda -march=sm_70 \ -// RUN: --libomptarget-nvptx-bc-path=%S/Inputs/libomptarget/libomptarget-new-nvptx-test.bc \ +// RUN: %clang -### -fopenmp=libomp --offload-arch=sm_89 \ // RUN: -nogpulib %s -o openmp-offload-gpu 2>&1 \ // RUN: | FileCheck -check-prefix=DRIVER_EMBEDDING %s diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c index aeddead6dbf8f4..f5d07454227906 100644 --- a/clang/test/Driver/pic.c +++ b/clang/test/Driver/pic.c @@ -128,15 +128,15 @@ // Make sure -pie is passed to along to ld and that the right *crt* files // are linked in. // RUN: %clang %s -target i386-unknown-freebsd -fPIE -pie -### \ -// RUN: --gcc-toolchain="" -rtlib=platform \ +// RUN: -rtlib=platform \ // RUN: --sysroot=%S/Inputs/basic_freebsd_tree 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIE-LD // RUN: %clang %s -target i386-linux-gnu -fPIE -pie -### \ -// RUN: --gcc-toolchain="" -rtlib=platform --unwindlib=platform \ +// RUN: -rtlib=platform --unwindlib=platform \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIE-LD // RUN: %clang %s -target i386-linux-gnu -fPIC -pie -### \ -// RUN: --gcc-toolchain="" -rtlib=platform --unwindlib=platform \ +// RUN: -rtlib=platform --unwindlib=platform \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIE-LD // @@ -149,7 +149,6 @@ // RUN: %clang -c %s -target i386-unknown-unknown -static -fPIC -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIC2 // RUN: %clang %s -target i386-linux-gnu -static -fPIC -### \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-STATIC // diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c index 052956dfa2dcea..ce4947d2bc47b4 100644 --- a/clang/test/Driver/riscv-features.c +++ b/clang/test/Driver/riscv-features.c @@ -41,10 +41,10 @@ // FAST-UNALIGNED-ACCESS: "-target-feature" "+fast-unaligned-access" // NO-FAST-UNALIGNED-ACCESS: "-target-feature" "-fast-unaligned-access" -// RUN: %clang --target=riscv32-unknown-elf --gcc-toolchain="" -### %s 2>&1 | FileCheck %s -check-prefix=NOUWTABLE -// RUN: %clang --target=riscv32-unknown-elf --gcc-toolchain="" -fasynchronous-unwind-tables -### %s 2>&1 | FileCheck %s -check-prefix=UWTABLE -// RUN: %clang --target=riscv64-unknown-elf --gcc-toolchain="" -### %s 2>&1 | FileCheck %s -check-prefix=NOUWTABLE -// RUN: %clang --target=riscv64-unknown-elf --gcc-toolchain="" -fasynchronous-unwind-tables -### %s 2>&1 | FileCheck %s -check-prefix=UWTABLE +// RUN: %clang --target=riscv32-unknown-elf -### %s 2>&1 | FileCheck %s -check-prefix=NOUWTABLE +// RUN: %clang --target=riscv32-unknown-elf -fasynchronous-unwind-tables -### %s 2>&1 | FileCheck %s -check-prefix=UWTABLE +// RUN: %clang --target=riscv64-unknown-elf -### %s 2>&1 | FileCheck %s -check-prefix=NOUWTABLE +// RUN: %clang --target=riscv64-unknown-elf -fasynchronous-unwind-tables -### %s 2>&1 | FileCheck %s -check-prefix=UWTABLE // // UWTABLE: "-funwind-tables=2" // NOUWTABLE-NOT: "-funwind-tables=2" diff --git a/clang/test/Driver/solaris-ld-sanitizer.c b/clang/test/Driver/solaris-ld-sanitizer.c index a59164787cada1..fbbd83f2d9e528 100644 --- a/clang/test/Driver/solaris-ld-sanitizer.c +++ b/clang/test/Driver/solaris-ld-sanitizer.c @@ -4,47 +4,47 @@ /// Check sparc-sun-solaris2.11, 32bit // RUN: %clang --target=sparc-sun-solaris2.11 %s -### -fuse-ld= \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LD %s /// Check sparc-sun-solaris2.11, 32bit // RUN: %clang -fsanitize=undefined --target=sparc-sun-solaris2.11 %s -### -fuse-ld= \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LD %s /// Check sparc-sun-solaris2.11, 64bit // RUN: %clang -m64 --target=sparc-sun-solaris2.11 %s -### -fuse-ld= \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LD %s /// Check sparc-sun-solaris2.11, 64bit // RUN: %clang -m64 -fsanitize=undefined --target=sparc-sun-solaris2.11 %s -### -fuse-ld= \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LD %s /// Check i386-pc-solaris2.11, 32bit // RUN: %clang --target=i386-pc-solaris2.11 %s -### -fuse-ld= \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LD %s /// Check i386-pc-solaris2.11, 32bit // RUN: %clang -fsanitize=undefined --target=i386-pc-solaris2.11 %s -### -fuse-ld= \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LD %s /// Check i386-pc-solaris2.11, 64bit // RUN: %clang -m64 --target=i386-pc-solaris2.11 %s -### -fuse-ld= \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LD %s // CHECK-LD-NOT: "-z" "relax=transtls" /// Check i386-pc-solaris2.11, 64bit // RUN: %clang -m64 -fsanitize=undefined --target=i386-pc-solaris2.11 %s -### -fuse-ld= \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LD-X64-UBSAN %s // RUN: %clang -m64 -fsanitize=undefined --target=i386-pc-solaris2.11 %s -### -fuse-ld=gld \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-GLD-X64-UBSAN %s // CHECK-LD-X64-UBSAN: "-z" "relax=transtls" @@ -56,12 +56,12 @@ /// Check i386-pc-solaris2.11, 32bit, shared libclang_rt.asan // RUN: %clang -fsanitize=address -shared-libasan --target=i386-pc-solaris2.11 %s -### 2>&1 \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree \ +// RUN: --sysroot=%S/Inputs/solaris_x86_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-X32-ASAN-SHARED %s // CHECK-LD-X32-ASAN-SHARED: "-z" "now" /// Check i386-pc-solaris2.11, 32bit, static libclang_rt.asan // RUN: %clang -fsanitize=address --target=i386-pc-solaris2.11 %s -### 2>&1 \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_x86_tree \ +// RUN: --sysroot=%S/Inputs/solaris_x86_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-X32-ASAN %s // CHECK-LD-X32-ASAN-NOT: "-z" "now" diff --git a/clang/test/Driver/solaris-ld-values.c b/clang/test/Driver/solaris-ld-values.c index d7b6734f9f91ec..6f0a5b5957f014 100644 --- a/clang/test/Driver/solaris-ld-values.c +++ b/clang/test/Driver/solaris-ld-values.c @@ -5,7 +5,6 @@ // Check sparc-sun-solaris2.11, 32bit // RUN: %clang -ansi -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-ANSI %s // CHECK-LD-SPARC32-ANSI: values-Xc.o @@ -13,7 +12,6 @@ // RUN: %clang -std=c89 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-C89 %s // CHECK-LD-SPARC32-C89: values-Xc.o @@ -21,7 +19,6 @@ // RUN: %clang -std=c90 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-C90 %s // CHECK-LD-SPARC32-C90: values-Xc.o @@ -29,7 +26,6 @@ // RUN: %clang -std=iso9899:199409 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-C94 %s // CHECK-LD-SPARC32-C94: values-Xc.o @@ -37,7 +33,6 @@ // RUN: %clang -std=c11 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-C11 %s // CHECK-LD-SPARC32-C11: values-Xc.o @@ -45,7 +40,6 @@ // RUN: %clang -std=gnu89 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-GNU89 %s // CHECK-LD-SPARC32-GNU89: values-Xa.o @@ -53,7 +47,6 @@ // RUN: %clang -std=gnu90 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-GNU90 %s // CHECK-LD-SPARC32-GNU90: values-Xa.o @@ -61,7 +54,6 @@ // RUN: %clang -std=gnu11 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-GNU11 %s // CHECK-LD-SPARC32-GNU11: values-Xa.o @@ -70,7 +62,6 @@ // Check i386-pc-solaris2.11, 32bit // RUN: %clang -ansi -### %s 2>&1 \ // RUN: --target=i386-pc-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_x86_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-X32-ANSI %s // CHECK-LD-X32-ANSI: values-Xc.o diff --git a/clang/test/Driver/solaris-ld-values.cpp b/clang/test/Driver/solaris-ld-values.cpp index 4230fabffcbbc6..566252f551d513 100644 --- a/clang/test/Driver/solaris-ld-values.cpp +++ b/clang/test/Driver/solaris-ld-values.cpp @@ -5,7 +5,6 @@ // Check sparc-sun-solaris2.11, 32bit // RUN: %clang -ansi -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-ANSI %s // CHECK-LD-SPARC32-ANSI: values-Xc.o @@ -13,7 +12,6 @@ // RUN: %clang -std=c++98 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-CPP98 %s // CHECK-LD-SPARC32-CPP98: values-Xc.o @@ -21,7 +19,6 @@ // RUN: %clang -std=c++11 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-CPP11 %s // CHECK-LD-SPARC32-CPP11: values-Xc.o @@ -29,7 +26,6 @@ // RUN: %clang -std=gnu++98 -### %s 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC32-GNUPP98 %s // CHECK-LD-SPARC32-GNUPP98: values-Xa.o @@ -38,7 +34,6 @@ // Check i386-pc-solaris2.11, 32bit // RUN: %clang -ANSI -### %s 2>&1 \ // RUN: --target=i386-pc-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_x86_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-X32-ANSI %s // CHECK-LD-X32-ANSI: values-Xa.o diff --git a/clang/test/Driver/solaris-ld.c b/clang/test/Driver/solaris-ld.c index df4fa7b4c9ebd6..6d74389e89222c 100644 --- a/clang/test/Driver/solaris-ld.c +++ b/clang/test/Driver/solaris-ld.c @@ -3,11 +3,9 @@ // Check sparc-sun-solaris2.11, 32bit // RUN: %clang -### %s --target=sparc-sun-solaris2.11 -fuse-ld= \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK-LD-SPARC32,CHECK-LD %s // RUN: %clang -### %s --target=sparc-sun-solaris2.11 -fuse-ld=gld \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefixes=CHECK-LD-SPARC32,CHECK-GLD %s // CHECK-LD-SPARC32-NOT: warning: @@ -31,7 +29,6 @@ // Check sparc-sun-solaris2.11, 64bit // RUN: %clang -m64 -### %s 2>&1 --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-SPARC64 %s // CHECK-LD-SPARC64-NOT: warning: @@ -53,7 +50,6 @@ // Check i386-pc-solaris2.11, 32bit // RUN: %clang -### %s 2>&1 --target=i386-pc-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_x86_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-X32 %s // CHECK-LD-X32-NOT: warning: @@ -76,7 +72,6 @@ // Check i386-pc-solaris2.11, 64bit // RUN: %clang -m64 -### %s 2>&1 \ // RUN: --target=i386-pc-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_x86_tree \ // RUN: | FileCheck --check-prefix=CHECK-LD-X64 %s // CHECK-LD-X64-NOT: warning: @@ -99,7 +94,6 @@ // Check the right -l flags are present with -shared // RUN: %clang -### %s -shared 2>&1 \ // RUN: --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree \ // RUN: | FileCheck --check-prefix=CHECK-SPARC32-SHARED %s // CHECK-SPARC32-SHARED: "{{.*}}ld{{(.exe)?}}" @@ -109,61 +103,51 @@ // Check that libm is only linked with clang++. // RUN: %clang -### %s --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOLIBM %s // RUN: %clang -### %s -shared --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOLIBM %s // RUN: %clangxx -### %s --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LIBM %s // RUN: %clangxx -### %s -shared --target=sparc-sun-solaris2.11 \ -// RUN: --gcc-toolchain="" --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ +// RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-LIBM %s // CHECK-LIBM: "-lm" // CHECK-NOLIBM-NOT: "-lm" // Check the right ld flags are present with -pie. // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -pie -fuse-ld= \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-PIE-LD %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -pie -fuse-ld=gld \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-PIE-GLD %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -no-pie -fuse-ld= \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOPIE-LD %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -no-pie -fuse-ld=gld \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOPIE-GLD %s // Check that -shared/-r/-static disable PIE. // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -shared -pie -fuse-ld= \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOPIE-LD %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -shared -pie -fuse-ld=gld \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOPIE-GLD %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -r -pie -fuse-ld= \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOPIE-LD %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -r -pie -fuse-ld=gld \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOPIE-GLD %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -static -pie -fuse-ld= \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOPIE-LD %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -static -pie -fuse-ld=gld \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOPIE-GLD %s @@ -184,19 +168,15 @@ // Check that crt{begin,end}S.o is linked with -shared/-pie. // RUN: %clang --target=sparc-sun-solaris2.11 -### %s \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTS %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -shared \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTS %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -no-pie \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTS %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -pie \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTS %s // CHECK-CRTS: crtbeginS.o @@ -208,11 +188,9 @@ // Check sparc-sun-solaris2.11, 32bit // RUN: %clang --target=sparc-sun-solaris2.11 -### %s \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH-SPARC32 %s // RUN: %clang --target=sparc-sun-solaris2.11 -### %s -ffast-math \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH-SPARC32 %s // CHECK-CRTFASTMATH-SPARC32: "-isysroot" "[[SYSROOT:[^"]+]]" @@ -221,11 +199,9 @@ // Check sparc-pc-solaris2.11, 64bit // RUN: %clang -m64 --target=sparc-sun-solaris2.11 -### %s \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH-SPARC64 %s // RUN: %clang -m64 --target=sparc-sun-solaris2.11 -### %s -ffast-math \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_sparc_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH-SPARC64 %s // CHECK-CRTFASTMATH-SPARC64: "-isysroot" "[[SYSROOT:[^"]+]]" @@ -234,11 +210,9 @@ // Check i386-pc-solaris2.11, 32bit // RUN: %clang --target=i386-pc-solaris2.11 -### %s \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH-X32 %s // RUN: %clang --target=i386-pc-solaris2.11 -### %s -ffast-math \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH-X32 %s // CHECK-CRTFASTMATH-X32: "-isysroot" "[[SYSROOT:[^"]+]]" @@ -247,11 +221,9 @@ // Check i386-pc-solaris2.11, 64bit // RUN: %clang -m64 --target=i386-pc-solaris2.11 -### %s \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NOCRTFASTMATH-X64 %s // RUN: %clang -m64 --target=i386-pc-solaris2.11 -### %s -ffast-math \ -// RUN: --gcc-toolchain="" \ // RUN: --sysroot=%S/Inputs/solaris_x86_tree 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-CRTFASTMATH-X64 %s // CHECK-CRTFASTMATH-X64: "-isysroot" "[[SYSROOT:[^"]+]]" diff --git a/clang/test/InstallAPI/diagnostics-dsym.test b/clang/test/InstallAPI/diagnostics-dsym.test new file mode 100644 index 00000000000000..c9cbeffef7bacc --- /dev/null +++ b/clang/test/InstallAPI/diagnostics-dsym.test @@ -0,0 +1,40 @@ +; REQUIRES: system-darwin +; REQUIRES: target-aarch64 + +; RUN: rm -rf %t +; RUN: split-file %s %t + +// Build a simple dylib with debug info. +; RUN: %clang --target=arm64-apple-macos11 -g -dynamiclib %t/foo.c \ +; RUN: -current_version 1 -compatibility_version 1 -L%t/usr/lib \ +; RUN: -save-temps \ +; RUN: -o %t/foo.dylib -install_name %t/foo.dylib +; RUN: dsymutil %t/foo.dylib -o %t/foo.dSYM + +; RUN: not clang-installapi -x c++ --target=arm64-apple-macos11 \ +; RUN: -install_name %t/foo.dylib \ +; RUN: -current_version 1 -compatibility_version 1 \ +; RUN: -o %t/output.tbd \ +; RUN: --verify-against=%t/foo.dylib --dsym=%t/foo.dSYM \ +; RUN: --verify-mode=Pedantic 2>&1 | FileCheck %s + +; CHECK: violations found for arm64 +; CHECK: foo.c:5:0: error: no declaration found for exported symbol 'bar' in dynamic library +; CHECK: foo.c:1:0: error: no declaration found for exported symbol 'foo' in dynamic library + +;--- foo.c +int foo(void) { + return 1; +} +extern char bar; +char bar = 'a'; + +;--- usr/lib/libSystem.tbd +--- !tapi-tbd +tbd-version: 4 +targets: [ arm64-macos ] +install-name: '/usr/lib/libSystem.B.dylib' +exports: + - targets: [ arm64-macos ] + symbols: [ dyld_stub_binder ] +... diff --git a/clang/test/Modules/language-linkage.cppm b/clang/test/Modules/language-linkage.cppm index bf7982cd9207d6..a5db9e9ebc07ec 100644 --- a/clang/test/Modules/language-linkage.cppm +++ b/clang/test/Modules/language-linkage.cppm @@ -14,5 +14,5 @@ void foo() {} extern "C" void bar() {} -// CHECK: define {{.*}}@bar( // CHECK: define {{.*}}@_Z3foov( +// CHECK: define {{.*}}@bar( diff --git a/clang/test/Modules/no-local-decl-in-reduced-bmi.cppm b/clang/test/Modules/no-local-decl-in-reduced-bmi.cppm new file mode 100644 index 00000000000000..41ae2bf0dec809 --- /dev/null +++ b/clang/test/Modules/no-local-decl-in-reduced-bmi.cppm @@ -0,0 +1,33 @@ +// Test that we won't record local declarations by default in reduced BMI. + +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: cd %t +// +// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-reduced-module-interface -o %t/a.pcm +// RUN: llvm-bcanalyzer --dump --disable-histogram --show-binary-blobs %t/a.pcm > %t/a.dump +// RUN: cat %t/a.dump | FileCheck %t/a.cppm +// +// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-reduced-module-interface -o %t/b.pcm +// RUN: llvm-bcanalyzer --dump --disable-histogram --show-binary-blobs %t/b.pcm > %t/b.dump +// RUN: cat %t/b.dump | FileCheck %t/b.cppm + +//--- a.cppm +export module a; +export int func() { + int v = 43; + return 43; +} + +// Test that the variable declaration is not recorded completely. +// CHECK-NOT: +struct __tuple_leaf : _Hp { + constexpr __tuple_leaf() : _Hp() {} +}; + +constexpr __tuple_leaf t; diff --git a/clang/test/Sema/constant-builtins-all-args-evaluated.cpp b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp new file mode 100644 index 00000000000000..db55e24cecda7a --- /dev/null +++ b/clang/test/Sema/constant-builtins-all-args-evaluated.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +constexpr int test_clzg_0() { + int x = 0; + (void)__builtin_clzg(0U, ++x); + return x; +} + +static_assert(test_clzg_0() == 1); + +constexpr int test_clzg_1() { + int x = 0; + (void)__builtin_clzg(1U, ++x); + return x; +} + +static_assert(test_clzg_1() == 1); + +constexpr int test_ctzg_0() { + int x = 0; + (void)__builtin_ctzg(0U, ++x); + return x; +} + +static_assert(test_ctzg_0() == 1); + +constexpr int test_ctzg_1() { + int x = 0; + (void)__builtin_ctzg(1U, ++x); + return x; +} + +static_assert(test_ctzg_1() == 1); diff --git a/clang/test/Sema/format-strings-signedness-fixit.c b/clang/test/Sema/format-strings-signedness-fixit.c new file mode 100644 index 00000000000000..b4e6e975657aae --- /dev/null +++ b/clang/test/Sema/format-strings-signedness-fixit.c @@ -0,0 +1,98 @@ +// RUN: cp %s %t +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -Wformat -Wformat-signedness -fixit %t +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -Wformat -Wformat-signedness -Werror %t +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -E -o - %t | FileCheck %s + +#include + +int printf(const char *restrict format, ...); + +void test_printf_int(int x) +{ + printf("%u", x); +} + +void test_printf_unsigned(unsigned x) +{ + printf("%d", x); +} + +void test_printf_long(long x) +{ + printf("%lu", x); +} + +void test_printf_unsigned_long(unsigned long x) +{ + printf("%ld", x); +} + +void test_printf_long_long(long long x) +{ + printf("%llu", x); +} + +void test_printf_unsigned_long_long(unsigned long long x) +{ + printf("%lld", x); +} + +enum enum_int { + minus_1 = -1 +}; + +void test_printf_enum_int(enum enum_int x) +{ + printf("%u", x); +} + +enum enum_unsigned { + zero = 0 +}; + +void test_printf_enum_unsigned(enum enum_unsigned x) +{ + printf("%d", x); +} + +enum enum_long { + minus_one = -1, + int_val = INT_MAX, + unsigned_val = (unsigned)INT_MIN +}; + +void test_printf_enum_long(enum enum_long x) +{ + printf("%lu", x); +} + +enum enum_unsigned_long { + uint_max_plus = (unsigned long)UINT_MAX+1, +}; + +void test_printf_enum_unsigned_long(enum enum_unsigned_long x) +{ + printf("%ld", x); +} + +// Validate the fixes. +// CHECK: void test_printf_int(int x) +// CHECK: printf("%d", x); +// CHECK: void test_printf_unsigned(unsigned x) +// CHECK: printf("%u", x); +// CHECK: void test_printf_long(long x) +// CHECK: printf("%ld", x); +// CHECK: void test_printf_unsigned_long(unsigned long x) +// CHECK: printf("%lu", x); +// CHECK: void test_printf_long_long(long long x) +// CHECK: printf("%lld", x); +// CHECK: void test_printf_unsigned_long_long(unsigned long long x) +// CHECK: printf("%llu", x); +// CHECK: void test_printf_enum_int(enum enum_int x) +// CHECK: printf("%d", x); +// CHECK: void test_printf_enum_unsigned(enum enum_unsigned x) +// CHECK: printf("%u", x); +// CHECK: void test_printf_enum_long(enum enum_long x) +// CHECK: printf("%ld", x); +// CHECK: void test_printf_enum_unsigned_long(enum enum_unsigned_long x) +// CHECK: printf("%lu", x); diff --git a/clang/test/Sema/format-strings-signedness.c b/clang/test/Sema/format-strings-signedness.c new file mode 100644 index 00000000000000..d5a8140d9ef8a0 --- /dev/null +++ b/clang/test/Sema/format-strings-signedness.c @@ -0,0 +1,222 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -verify -Wformat -Wformat-signedness %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -std=c11 -fsyntax-only -verify -Wformat -Wformat-signedness %s + +// Verify that -Wformat-signedness alone (without -Wformat) trigger the +// warnings. Note in gcc this will not trigger the signedness warnings as +// -Wformat is default off in gcc. +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -verify -Wformat-signedness %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -std=c11 -fsyntax-only -verify -Wformat-signedness %s + +// Verify that -Wformat-signedness warnings are not reported with only -Wformat +// (gcc compat). +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -Wformat -verify=okay %s + +// Verify that -Wformat-signedness with -Wno-format are not reported (gcc compat). +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -Wformat-signedness -Wno-format -verify=okay %s +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -std=c11 -fsyntax-only -Wno-format -Wformat-signedness -verify=okay %s +// okay-no-diagnostics + +int printf(const char *restrict format, ...); +int scanf(const char * restrict, ...); + +void test_printf_bool(_Bool x) +{ + printf("%d", x); // no-warning + printf("%u", x); // no-warning + printf("%x", x); // no-warning +} + +void test_printf_char(char x) +{ + printf("%c", x); // no-warning +} + +void test_printf_unsigned_char(unsigned char x) +{ + printf("%c", x); // no-warning +} + +void test_printf_int(int x) +{ + printf("%d", x); // no-warning + printf("%u", x); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'int'}} + printf("%x", x); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'int'}} +} + +void test_printf_unsigned(unsigned x) +{ + printf("%d", x); // expected-warning{{format specifies type 'int' but the argument has type 'unsigned int'}} + printf("%u", x); // no-warning + printf("%x", x); // no-warning +} + +void test_printf_long(long x) +{ + printf("%ld", x); // no-warning + printf("%lu", x); // expected-warning{{format specifies type 'unsigned long' but the argument has type 'long'}} + printf("%lx", x); // expected-warning{{format specifies type 'unsigned long' but the argument has type 'long'}} +} + +void test_printf_unsigned_long(unsigned long x) +{ + printf("%ld", x); // expected-warning{{format specifies type 'long' but the argument has type 'unsigned long'}} + printf("%lu", x); // no-warning + printf("%lx", x); // no-warning +} + +void test_printf_long_long(long long x) +{ + printf("%lld", x); // no-warning + printf("%llu", x); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'long long'}} + printf("%llx", x); // expected-warning{{format specifies type 'unsigned long long' but the argument has type 'long long'}} +} + +void test_printf_unsigned_long_long(unsigned long long x) +{ + printf("%lld", x); // expected-warning{{format specifies type 'long long' but the argument has type 'unsigned long long'}} + printf("%llu", x); // no-warning + printf("%llx", x); // no-warning +} + +enum enum_int { + minus_1 = -1 +}; + +void test_printf_enum_int(enum enum_int x) +{ + printf("%d", x); // no-warning + printf("%u", x); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'int'}} + printf("%x", x); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'int'}} +} + +#ifndef _WIN32 // Disabled due to enums have different underlying type on _WIN32 +enum enum_unsigned { + zero = 0 +}; + +void test_printf_enum_unsigned(enum enum_unsigned x) +{ + printf("%d", x); // expected-warning{{format specifies type 'int' but the argument has underlying type 'unsigned int'}} + printf("%u", x); // no-warning + printf("%x", x); // no-warning +} + +enum enum_long { + minus_one = -1, + int_val = __INT_MAX__, // INT_MAX + unsigned_val = (unsigned)(-__INT_MAX__ -1) // (unsigned)INT_MIN +}; + +void test_printf_enum_long(enum enum_long x) +{ + printf("%ld", x); // no-warning + printf("%lu", x); // expected-warning{{format specifies type 'unsigned long' but the argument has underlying type 'long'}} + printf("%lx", x); // expected-warning{{format specifies type 'unsigned long' but the argument has underlying type 'long'}} +} + +enum enum_unsigned_long { + uint_max_plus = (unsigned long)(__INT_MAX__ *2U +1U)+1, // (unsigned long)UINT_MAX+1 +}; + +void test_printf_enum_unsigned_long(enum enum_unsigned_long x) +{ + printf("%ld", x); // expected-warning{{format specifies type 'long' but the argument has underlying type 'unsigned long'}} + printf("%lu", x); // no-warning + printf("%lx", x); // no-warning +} +#endif + +void test_scanf_char(char *y) { + scanf("%c", y); // no-warning +} + +void test_scanf_unsigned_char(unsigned char *y) { + scanf("%c", y); // no-warning +} + +void test_scanf_int(int *x) { + scanf("%d", x); // no-warning + scanf("%u", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'int *'}} + scanf("%x", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'int *'}} +} + +void test_scanf_unsigned(unsigned *x) { + scanf("%d", x); // expected-warning{{format specifies type 'int *' but the argument has type 'unsigned int *'}} + scanf("%u", x); // no-warning + scanf("%x", x); // no-warning +} + +void test_scanf_long(long *x) { + scanf("%ld", x); // no-warning + scanf("%lu", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'long *'}} + scanf("%lx", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'long *'}} +} + +void test_scanf_unsigned_long(unsigned long *x) { + scanf("%ld", x); // expected-warning{{format specifies type 'long *' but the argument has type 'unsigned long *'}} + scanf("%lu", x); // no-warning + scanf("%lx", x); // no-warning +} + +void test_scanf_longlong(long long *x) { + scanf("%lld", x); // no-warning + scanf("%llu", x); // expected-warning{{format specifies type 'unsigned long long *' but the argument has type 'long long *'}} + scanf("%llx", x); // expected-warning{{format specifies type 'unsigned long long *' but the argument has type 'long long *'}} +} + +void test_scanf_unsigned_longlong(unsigned long long *x) { + scanf("%lld", x); // expected-warning{{format specifies type 'long long *' but the argument has type 'unsigned long long *'}} + scanf("%llu", x); // no-warning + scanf("%llx", x); // no-warning +} + +void test_scanf_enum_int(enum enum_int *x) { + scanf("%d", x); // no-warning + scanf("%u", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'enum enum_int *'}} + scanf("%x", x); // expected-warning{{format specifies type 'unsigned int *' but the argument has type 'enum enum_int *'}} +} + +#ifndef _WIN32 // Disabled due to enums have different underlying type on _WIN32 +void test_scanf_enum_unsigned(enum enum_unsigned *x) { + scanf("%d", x); // expected-warning{{format specifies type 'int *' but the argument has type 'enum enum_unsigned *'}} + scanf("%u", x); // no-warning + scanf("%x", x); // no-warning +} + +void test_scanf_enum_long(enum enum_long *x) { + scanf("%ld", x); // no-warning + scanf("%lu", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'enum enum_long *'}} + scanf("%lx", x); // expected-warning{{format specifies type 'unsigned long *' but the argument has type 'enum enum_long *'}} +} + +void test_scanf_enum_unsigned_long(enum enum_unsigned_long *x) { + scanf("%ld", x); // expected-warning{{format specifies type 'long *' but the argument has type 'enum enum_unsigned_long *'}} + scanf("%lu", x); // no-warning + scanf("%lx", x); // no-warning +} +#endif + +// Verify that we get no warnings from + +typedef short int int16_t; +typedef unsigned short int uint16_t; + +void test_printf_priX16(int16_t x) { + printf("PRId16: %" "d" /*PRId16*/ "\n", x); // no-warning + printf("PRIi16: %" "i" /*PRIi16*/ "\n", x); // no-warning +} + +void test_printf_unsigned_priX16(uint16_t x) { + printf("PRIo16: %" "o" /*PRIo16*/ "\n", x); // no-warning + printf("PRIu16: %" "u" /*PRIu16*/ "\n", x); // no-warning + printf("PRIx16: %" "x" /*PRIx16*/ "\n", x); // no-warning + printf("PRIX16: %" "X" /*PRIX16*/ "\n", x); // no-warning +} + +// Verify that we can suppress a -Wformat-signedness warning by ignoring +// -Wformat (gcc compat). +void test_suppress(int x) +{ +#pragma GCC diagnostic ignored "-Wformat" + printf("%u", x); +} diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp index ce403285b0f531..b71cd46f884d63 100644 --- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp +++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp @@ -259,3 +259,23 @@ using Bar2 = Foo; // expected-error {{extraneous template parameter list in a Bar2 b = 1; // expected-error {{no viable constructor or deduction guide for deduction of template arguments}} } // namespace test19 + +// GH85385 +namespace test20 { +template