diff options
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 60 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 29 | ||||
-rw-r--r-- | test/CodeGen/Generic/promote-integers.ll | 15 |
3 files changed, 99 insertions, 5 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 3093ddfc29..7685e2d6ab 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1597,6 +1597,13 @@ private: const TargetData *TD; const TargetLoweringObjectFile &TLOF; + /// We are in the process of implementing a new TypeLegalization action + /// which is the promotion of vector elements. This feature is under + /// development. Until this feature is complete, it is only enabled using a + /// flag. We pass this flag using a member because of circular dep issues. + /// This member will be removed with the flag once we complete the transition. + bool mayPromoteElements; + /// PointerTy - The type to use for pointers, usually i32 or i64. /// MVT PointerTy; @@ -1756,10 +1763,10 @@ private: EVT NVT = TransformToType[VT.getSimpleVT().SimpleTy]; LegalizeTypeAction LA = ValueTypeActions.getTypeAction(VT.getSimpleVT()); - assert((NVT.isSimple() && LA != TypeLegal )? - ValueTypeActions.getTypeAction( - NVT.getSimpleVT()) != TypePromoteInteger - : 1 && "Promote may not follow Expand or Promote"); + assert( + (!(NVT.isSimple() && LA != TypeLegal) || + ValueTypeActions.getTypeAction(NVT.getSimpleVT()) != TypePromoteInteger) + && "Promote may not follow Expand or Promote"); return LegalizeKind(LA, NVT); } @@ -1791,6 +1798,51 @@ private: if (NumElts == 1) return LegalizeKind(TypeScalarizeVector, EltVT); + // If we allow the promotion of vector elements using a flag, + // then try to widen vector elements until a legal type is found. + if (mayPromoteElements && EltVT.isInteger()) { + // Vectors with a number of elements that is not a power of two are always + // widened, for example <3 x float> -> <4 x float>. + if (!VT.isPow2VectorType()) { + NumElts = (unsigned)NextPowerOf2(NumElts); + EVT NVT = EVT::getVectorVT(Context, EltVT, NumElts); + return LegalizeKind(TypeWidenVector, NVT); + } + + // Examine the element type. + LegalizeKind LK = getTypeConversion(Context, EltVT); + + // If type is to be expanded, split the vector. + // <4 x i140> -> <2 x i140> + if (LK.first == TypeExpandInteger) + return LegalizeKind(TypeSplitVector, + EVT::getVectorVT(Context, EltVT, NumElts / 2)); + + // Promote the integer element types until a legal vector type is found + // or until the element integer type is too big. If a legal type was not + // found, fallback to the usual mechanism of widening/splitting the + // vector. + while (1) { + // Increase the bitwidth of the element to the next pow-of-two + // (which is greater than 8 bits). + EltVT = EVT::getIntegerVT(Context, 1 + EltVT.getSizeInBits() + ).getRoundIntegerType(Context); + + // Stop trying when getting a non-simple element type. + // Note that vector elements may be greater than legal vector element + // types. Example: X86 XMM registers hold 64bit element on 32bit systems. + if (!EltVT.isSimple()) break; + + // Build a new vector type and check if it is legal. + MVT NVT = MVT::getVectorVT(EltVT.getSimpleVT(), NumElts); + + // Found a legal promoted vector type. + if (ValueTypeActions.getTypeAction(NVT) == TypeLegal) + return LegalizeKind(TypePromoteInteger, + EVT::getVectorVT(Context, EltVT, NumElts)); + } + } + // Try to widen the vector until a legal type is found. // If there is no wider legal type, split the vector. while (1) { diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 97de73151e..a9ac786dc6 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -26,11 +26,19 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include <cctype> using namespace llvm; +/// We are in the process of implementing a new TypeLegalization action +/// - the promotion of vector elements. This feature is disabled by default +/// and only enabled using this flag. +static cl::opt<bool> +AllowPromoteIntElem("promote-elements", cl::Hidden, + cl::desc("Allow promotion of integer vector element types")); + namespace llvm { TLSModel::Model getTLSModel(const GlobalValue *GV, Reloc::Model reloc) { bool isLocal = GV->hasLocalLinkage(); @@ -528,7 +536,8 @@ static void InitCmpLibcallCCs(ISD::CondCode *CCs) { /// NOTE: The constructor takes ownership of TLOF. TargetLowering::TargetLowering(const TargetMachine &tm, const TargetLoweringObjectFile *tlof) - : TM(tm), TD(TM.getTargetData()), TLOF(*tlof) { + : TM(tm), TD(TM.getTargetData()), TLOF(*tlof), + mayPromoteElements(AllowPromoteIntElem) { // All operations default to being supported. memset(OpActions, 0, sizeof(OpActions)); memset(LoadExtActions, 0, sizeof(LoadExtActions)); @@ -814,6 +823,24 @@ void TargetLowering::computeRegisterProperties() { bool IsLegalWiderType = false; for (unsigned nVT = i+1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) { EVT SVT = (MVT::SimpleValueType)nVT; + + // If we allow the promotion of vector elements using a flag, + // then return TypePromoteInteger on vector elements. + if (mayPromoteElements) { + // Promote vectors of integers to vectors with the same number + // of elements, with a wider element type. + if (SVT.getVectorElementType().getSizeInBits() > EltVT.getSizeInBits() + && SVT.getVectorNumElements() == NElts && + isTypeLegal(SVT) && SVT.getScalarType().isInteger()) { + TransformToType[i] = SVT; + RegisterTypeForVT[i] = SVT; + NumRegistersForVT[i] = 1; + ValueTypeActions.setTypeAction(VT, TypePromoteInteger); + IsLegalWiderType = true; + break; + } + } + if (SVT.getVectorElementType() == EltVT && SVT.getVectorNumElements() > NElts && isTypeLegal(SVT)) { diff --git a/test/CodeGen/Generic/promote-integers.ll b/test/CodeGen/Generic/promote-integers.ll new file mode 100644 index 0000000000..58125921b3 --- /dev/null +++ b/test/CodeGen/Generic/promote-integers.ll @@ -0,0 +1,15 @@ +; Test that vectors are scalarized/lowered correctly. +; RUN: llc -march=x86 -promote-elements < %s | FileCheck %s + +; This test is the poster-child for integer-element-promotion. +; Until this feature is complete, we mark this test as expected to fail. +; XFAIL: * +; CHECK: vector_code +; CHECK: ret +define <4 x float> @vector_code(<4 x i64> %A, <4 x i64> %B, <4 x float> %R0, <4 x float> %R1 ) { + %C = icmp eq <4 x i64> %A, %B + %K = xor <4 x i1> <i1 1, i1 1, i1 1, i1 1>, %C + %D = select <4 x i1> %K, <4 x float> %R1, <4 x float> %R0 + ret <4 x float> %D +} + |