Index: lib/Target/SystemZ/SystemZISelLowering.h =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.h +++ lib/Target/SystemZ/SystemZISelLowering.h @@ -516,6 +516,7 @@ static bool tryBuildVectorByteMask(BuildVectorSDNode *BVN, uint64_t &Mask); static bool analyzeFPImm(const APFloat &Imm, unsigned BitWidth, unsigned &Start, unsigned &End, const SystemZInstrInfo *TII); + bool isBuildVectorAllLegalFPImms(BuildVectorSDNode *BVN) const; private: const SystemZSubtarget &Subtarget; Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -4559,6 +4559,24 @@ return Result; } +bool SystemZTargetLowering:: +isBuildVectorAllLegalFPImms(BuildVectorSDNode *BVN) const { + EVT VT = BVN->getValueType(0); + unsigned NumElements = VT.getVectorNumElements(); + EVT EltVT = VT.getScalarType(); + if (!EltVT.isFloatingPoint()) + return false; + for (unsigned I = 0; I < NumElements; ++I) { + SDValue Op = BVN->getOperand(I); + if (Op.isUndef()) + continue; + ConstantFPSDNode *FPImm = dyn_cast(Op); + if (FPImm == nullptr || !isFPImmLegal(FPImm->getValueAPF(), EltVT)) + return false; + } + return true; +} + SDValue SystemZTargetLowering::lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const { const SystemZInstrInfo *TII = @@ -4574,7 +4592,8 @@ uint64_t Mask; if (ISD::isBuildVectorAllZeros(Op.getNode()) || ISD::isBuildVectorAllOnes(Op.getNode()) || - (VT.isInteger() && tryBuildVectorByteMask(BVN, Mask))) + (tryBuildVectorByteMask(BVN, Mask) && + (VT.isInteger() || isBuildVectorAllLegalFPImms(BVN)))) return Op; // Try using some form of replication. Index: test/CodeGen/SystemZ/vec-const-05.ll =================================================================== --- test/CodeGen/SystemZ/vec-const-05.ll +++ test/CodeGen/SystemZ/vec-const-05.ll @@ -1,28 +1,63 @@ -; Test vector byte masks, v4f32 version. Only all-zero vectors are handled. +; Test vector byte masks, v4f32 version. ; ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s ; Test an all-zeros vector. -define <4 x float> @f0() { -; CHECK-LABEL: f0: +define <4 x float> @f1() { +; CHECK-LABEL: f1: ; CHECK: vgbm %v24, 0 ; CHECK: br %r14 ret <4 x float> zeroinitializer } -; Test that undefs are treated as zero. -define <4 x float> @f1() { -; CHECK-LABEL: f1: -; CHECK: vgbm %v24, 0 +; Test an all-ones vector. +define <4 x float> @f2() { +; CHECK-LABEL: f2: +; CHECK: vgbm %v24, 65535 ; CHECK: br %r14 - ret <4 x float> + ret <4 x float> +} + +; Test a mixed vector (mask 0xc731). +define <4 x float> @f3() { +; CHECK-LABEL: f3: +; CHECK: vgbm %v24, 50993 +; CHECK: br %r14 + ret <4 x float> +} + +; Test that undefs are treated as zero (mask 0xc031). +define <4 x float> @f4() { +; CHECK-LABEL: f4: +; CHECK: vgbm %v24, 49201 +; CHECK: br %r14 + ret <4 x float> +} + +; Test that we don't use VGBM if one of the bytes is not 0 or 0xff. +define <4 x float> @f5() { +; CHECK-LABEL: f5: +; CHECK-NOT: vgbm +; CHECK: br %r14 + ret <4 x float> } ; Test an all-zeros v2f32 that gets promoted to v4f32. -define <2 x float> @f2() { -; CHECK-LABEL: f2: +define <2 x float> @f6() { +; CHECK-LABEL: f6: ; CHECK: vgbm %v24, 0 ; CHECK: br %r14 ret <2 x float> zeroinitializer } + +; Test a mixed v2f32 that gets promoted to v4f32 (mask 0xc700). +define <2 x float> @f7() { +; CHECK-LABEL: f7: +; CHECK: vgbm %v24, 50944 +; CHECK: br %r14 + ret <2 x float> +} Index: test/CodeGen/SystemZ/vec-const-06.ll =================================================================== --- test/CodeGen/SystemZ/vec-const-06.ll +++ test/CodeGen/SystemZ/vec-const-06.ll @@ -1,19 +1,35 @@ -; Test vector byte masks, v2f64 version. Only all-zero vectors are handled. +; Test vector byte masks, v2f64 version. ; ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s ; Test an all-zeros vector. -define <2 x double> @f0() { -; CHECK-LABEL: f0: +define <2 x double> @f1() { +; CHECK-LABEL: f1: ; CHECK: vgbm %v24, 0 ; CHECK: br %r14 ret <2 x double> zeroinitializer } +; Test an all-ones vector. +define <2 x double> @f2() { +; CHECK-LABEL: f2: +; CHECK: vgbm %v24, 65535 +; CHECK: br %r14 + ret <2 x double> +} + ; Test that undefs are treated as zero. -define <2 x double> @f1() { -; CHECK-LABEL: f1: -; CHECK: vgbm %v24, 0 +define <2 x double> @f3() { +; CHECK-LABEL: f3: +; CHECK: vgbm %v24, 65280 +; CHECK: br %r14 + ret <2 x double> +} + +; Test that we don't use VGBM if one of the bytes is not 0 or 0xff. +define <2 x double> @f4() { +; CHECK-LABEL: f4: +; CHECK-NOT: vgbm ; CHECK: br %r14 - ret <2 x double> + ret <2 x double> }