diff options
| author | Kevin Qin <Kevin.Qin@arm.com> | 2014-07-07 02:45:40 +0000 |
|---|---|---|
| committer | Kevin Qin <Kevin.Qin@arm.com> | 2014-07-07 02:45:40 +0000 |
| commit | 4473c1943ffd41ce0ed6898f688b8f75c6a58dd9 (patch) | |
| tree | a3ade10342844339ef1587ea866b2b49871922af | |
| parent | 9d85b18f91a7596934f7928eccca828698635139 (diff) | |
| download | bcm5719-llvm-4473c1943ffd41ce0ed6898f688b8f75c6a58dd9.tar.gz bcm5719-llvm-4473c1943ffd41ce0ed6898f688b8f75c6a58dd9.zip | |
[AArch64] Normalize all constants to build a vector.
The value of constant operands will be truncated to fit element width.
llvm-svn: 212428
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 28 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AArch64/arm64-build-vector.ll | 2 |
2 files changed, 28 insertions, 2 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 1c1be657680..28d0035a11a 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -5181,11 +5181,37 @@ FailedModImm: return Op; } +// Normalize the operands of BUILD_VECTOR. The value of constant operands will +// be truncated to fit element width. +static SDValue NormalizeBuildVector(SDValue Op, + SelectionDAG &DAG) { + assert(Op.getOpcode() == ISD::BUILD_VECTOR && "Unknown opcode!"); + SDLoc dl(Op); + EVT VT = Op.getValueType(); + EVT EltTy= VT.getVectorElementType(); + + if (EltTy.isFloatingPoint() || EltTy.getSizeInBits() > 16) + return Op; + + SmallVector<SDValue, 16> Ops; + for (unsigned I = 0, E = VT.getVectorNumElements(); I != E; ++I) { + SDValue Lane = Op.getOperand(I); + if (Lane.getOpcode() == ISD::Constant) { + APInt LowBits(EltTy.getSizeInBits(), + cast<ConstantSDNode>(Lane)->getZExtValue()); + Lane = DAG.getConstant(LowBits.getZExtValue(), MVT::i32); + } + Ops.push_back(Lane); + } + return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, Ops); +} + SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const { - BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Op.getNode()); SDLoc dl(Op); EVT VT = Op.getValueType(); + Op = NormalizeBuildVector(Op, DAG); + BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(Op.getNode()); APInt CnstBits(VT.getSizeInBits(), 0); APInt UndefBits(VT.getSizeInBits(), 0); diff --git a/llvm/test/CodeGen/AArch64/arm64-build-vector.ll b/llvm/test/CodeGen/AArch64/arm64-build-vector.ll index 00c0bc7cd3a..7a3c8cec7d9 100644 --- a/llvm/test/CodeGen/AArch64/arm64-build-vector.ll +++ b/llvm/test/CodeGen/AArch64/arm64-build-vector.ll @@ -36,7 +36,7 @@ define <4 x float> @foo(float %a, float %b, float %c, float %d) nounwind { define <8 x i16> @build_all_zero(<8 x i16> %a) #1 { ; CHECK-LABEL: build_all_zero: -; CHECK: movn w[[GREG:[0-9]+]], #0x517f +; CHECK: movz w[[GREG:[0-9]+]], #0xae80 ; CHECK-NEXT: fmov s[[FREG:[0-9]+]], w[[GREG]] ; CHECK-NEXT: mul.8h v0, v0, v[[FREG]] %b = add <8 x i16> %a, <i16 -32768, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef> |

