diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5039,6 +5039,21 @@ RenderTargetOptions(Triple, Args, KernelOrKext, CmdArgs); + // FIXME: For now we want to demote any errors to warnings, when they have + // been raised for asking the wrong question of scalable vectors, such as + // asking for the fixed number of elements. This may happen because code that + // is not yet ported to work for scalable vectors uses the wrong interfaces, + // whereas the behaviour is actually correct. Emitting a warning helps bring + // up scalable vector support in an incremental way. When scalable vector + // support is stable enough, all uses of wrong interfaces should be considered + // as errors, but until then, we can live with a warning being emitted by the + // compiler. This way, Clang can be used to compile code with scalable vectors + // and identify possible issues. + if (isa(JA)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-treat-scalable-fixed-error-as-warning"); + } + // These two are potentially updated by AddClangCLArgs. codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo; bool EmitCodeView = false; diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -298,21 +298,7 @@ } /// Given a vector type, return the number of elements it contains. - unsigned getVectorNumElements() const { -#ifdef STRICT_FIXED_SIZE_VECTORS - assert(isFixedLengthVector() && "Invalid vector type!"); -#else - assert(isVector() && "Invalid vector type!"); - if (isScalableVector()) - WithColor::warning() - << "Possible incorrect use of EVT::getVectorNumElements() for " - "scalable vector. Scalable flag may be dropped, use " - "EVT::getVectorElementCount() instead\n"; -#endif - if (isSimple()) - return V.getVectorNumElements(); - return getExtendedVectorNumElements(); - } + unsigned getVectorNumElements() const; // Given a (possibly scalable) vector type, return the ElementCount ElementCount getVectorElementCount() const { diff --git a/llvm/include/llvm/Support/TypeSize.h b/llvm/include/llvm/Support/TypeSize.h --- a/llvm/include/llvm/Support/TypeSize.h +++ b/llvm/include/llvm/Support/TypeSize.h @@ -16,6 +16,7 @@ #define LLVM_SUPPORT_TYPESIZE_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/WithColor.h" @@ -27,6 +28,12 @@ namespace llvm { +namespace TypeSizeClOpt { +/// The ScalableErrorAsWarning is a temporary measure to suppress errors from +/// using the wrong interface. +extern cl::opt ScalableErrorAsWarning; +} // namespace TypeSizeClOpt + template struct LinearPolyBaseTypeTraits {}; //===----------------------------------------------------------------------===// @@ -446,17 +453,7 @@ // else // bail out early for scalable vectors and use getFixedValue() // } - operator ScalarTy() const { -#ifdef STRICT_FIXED_SIZE_VECTORS - return getFixedValue(); -#else - if (isScalable()) - WithColor::warning() << "Compiler has made implicit assumption that " - "TypeSize is not scalable. This may or may not " - "lead to broken code.\n"; - return getKnownMinValue(); -#endif - } + operator ScalarTy() const; // Additional operators needed to avoid ambiguous parses // because of the implicit conversion hack. diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4329,7 +4329,10 @@ if (Q.isUndefValue(Ops[0])) return UndefValue::get(GEPTy); - bool IsScalableVec = isa(SrcTy); + bool IsScalableVec = + isa(SrcTy) || any_of(Ops, [](const Value *V) { + return isa(V->getType()); + }); if (Ops.size() == 2) { // getelementptr P, 0 -> P. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4777,8 +4777,8 @@ assert(VT.isVector() && "This DAG node is restricted to vector types."); assert(Operand.getValueType().bitsLE(VT) && "The input must be the same size or smaller than the result."); - assert(VT.getVectorNumElements() < - Operand.getValueType().getVectorNumElements() && + assert(VT.getVectorMinNumElements() < + Operand.getValueType().getVectorMinNumElements() && "The destination vector type must have fewer lanes than the input."); break; case ISD::ABS: diff --git a/llvm/lib/CodeGen/ValueTypes.cpp b/llvm/lib/CodeGen/ValueTypes.cpp --- a/llvm/lib/CodeGen/ValueTypes.cpp +++ b/llvm/lib/CodeGen/ValueTypes.cpp @@ -14,6 +14,31 @@ #include "llvm/Support/TypeSize.h" using namespace llvm; +unsigned EVT::getVectorNumElements() const { + auto Error = []() { + report_fatal_error( + "Cannot return the exact number of elements of a scalable vector!"); + }; +#ifdef STRICT_FIXED_SIZE_VECTORS + if (isScalableVector()) + Error(); +#else + assert(isVector() && "Invalid vector type!"); + if (isScalableVector()) { + if (llvm::TypeSizeClOpt::ScalableErrorAsWarning) + WithColor::warning() + << "Possible incorrect use of EVT::getVectorNumElements() for " + "scalable vector. Scalable flag may be dropped, use " + "EVT::getVectorElementCount() instead\n"; + else + Error(); + } +#endif + if (isSimple()) + return V.getVectorNumElements(); + return getExtendedVectorNumElements(); +} + EVT EVT::changeExtendedTypeToInteger() const { assert(isExtended() && "Type is not extended!"); LLVMContext &Context = LLVMTy->getContext(); diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -185,6 +185,7 @@ TrigramIndex.cpp Triple.cpp Twine.cpp + TypeSize.cpp Unicode.cpp UnicodeCaseFold.cpp VersionTuple.cpp diff --git a/llvm/lib/Support/TypeSize.cpp b/llvm/lib/Support/TypeSize.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Support/TypeSize.cpp @@ -0,0 +1,39 @@ +//===- TypeSize.cpp - Wrapper around type sizes------------------*- 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 "llvm/Support/TypeSize.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; + +cl::opt llvm::TypeSizeClOpt::ScalableErrorAsWarning( + "treat-scalable-fixed-error-as-warning", cl::Hidden, cl::init(false), + cl::desc("Treat issues where a fixed-width property is requested from a " + "scalable type as a warning, instead of an error."), + cl::ZeroOrMore); + +TypeSize::operator TypeSize::ScalarTy() const { + auto Error = []() { + report_fatal_error("Cannot convert a scalable size to a fixed-width size!"); + }; +#ifdef STRICT_FIXED_SIZE_VECTORS + if (isScalable()) + Error(); +#else + if (isScalable()) { + if (llvm::TypeSizeClOpt::ScalableErrorAsWarning) { + WithColor::warning() << "Compiler has made implicit assumption that " + "TypeSize is not scalable. This may or may not " + "lead to broken code.\n"; + return getKnownMinValue(); + } else + Error(); + } + return getFixedValue(); +#endif +} diff --git a/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp b/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp --- a/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp +++ b/llvm/unittests/CodeGen/ScalableVectorMVTsTest.cpp @@ -180,7 +180,8 @@ // Check convenience size scaling methods. EXPECT_EQ(v2i32.getSizeInBits() * 2, v4i32.getSizeInBits()); EXPECT_EQ(2 * nxv2i32.getSizeInBits(), nxv4i32.getSizeInBits()); - EXPECT_EQ(nxv2f64.getSizeInBits() / 2, nxv2i32.getSizeInBits()); + EXPECT_EQ(nxv2f64.getSizeInBits().divideCoefficientBy(2), + nxv2i32.getSizeInBits()); } } // end anonymous namespace diff --git a/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp b/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp --- a/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp +++ b/llvm/unittests/CodeGen/SelectionDAGAddressAnalysisTest.cpp @@ -169,10 +169,10 @@ TypeSize Offset1 = SubVecVT.getStoreSize(); SDValue Index0 = DAG->getMemBasePlusOffset(FIPtr, Offset0, Loc); SDValue Index1 = DAG->getMemBasePlusOffset(FIPtr, Offset1, Loc); - SDValue Store0 = DAG->getStore(DAG->getEntryNode(), Loc, Value, Index0, - PtrInfo.getWithOffset(Offset0)); + SDValue Store0 = + DAG->getStore(DAG->getEntryNode(), Loc, Value, Index0, PtrInfo); SDValue Store1 = DAG->getStore(DAG->getEntryNode(), Loc, Value, Index1, - PtrInfo.getWithOffset(Offset1)); + MachinePointerInfo(PtrInfo.getAddrSpace())); Optional NumBytes0 = MemoryLocation::getSizeOrUnknown( cast(Store0)->getMemoryVT().getStoreSize()); Optional NumBytes1 = MemoryLocation::getSizeOrUnknown(