diff options
author | Eli Friedman <efriedma@codeaurora.org> | 2019-01-15 00:15:24 +0000 |
---|---|---|
committer | Eli Friedman <efriedma@codeaurora.org> | 2019-01-15 00:15:24 +0000 |
commit | 866322034b8f0a9a4b83b8ece347222af09ad550 (patch) | |
tree | 9a46947568c41bc2049c2f6d7fe5f812e5557167 /llvm | |
parent | f56c613db27a8a354108e385d4e29cb120101762 (diff) |
[AArch64] Explicitly use v1i64 type for llvm.aarch64.neon.abs.i64 .
Otherwise, with D56544, the intrinsic will be expanded to an integer
csel, which is probably not what the user expected. This matches the
general convention of using "v1" types to represent scalar integer
operations in vector registers.
While I'm here, also add some error checking so we don't generate
illegal ABS nodes.
Differential Revision: https://reviews.llvm.org/D56616
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 16 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/arm64-vabs.ll | 3 |
2 files changed, 14 insertions, 5 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 0e5e6d4acc0..e01ca14d7f6 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -2718,9 +2718,19 @@ SDValue AArch64TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, EVT PtrVT = getPointerTy(DAG.getDataLayout()); return DAG.getNode(AArch64ISD::THREAD_POINTER, dl, PtrVT); } - case Intrinsic::aarch64_neon_abs: - return DAG.getNode(ISD::ABS, dl, Op.getValueType(), - Op.getOperand(1)); + case Intrinsic::aarch64_neon_abs: { + EVT Ty = Op.getValueType(); + if (Ty == MVT::i64) { + SDValue Result = DAG.getNode(ISD::BITCAST, dl, MVT::v1i64, + Op.getOperand(1)); + Result = DAG.getNode(ISD::ABS, dl, MVT::v1i64, Result); + return DAG.getNode(ISD::BITCAST, dl, MVT::i64, Result); + } else if (Ty.isVector() && Ty.isInteger() && isTypeLegal(Ty)) { + return DAG.getNode(ISD::ABS, dl, Ty, Op.getOperand(1)); + } else { + report_fatal_error("Unexpected type for AArch64 NEON intrinic"); + } + } case Intrinsic::aarch64_neon_smax: return DAG.getNode(ISD::SMAX, dl, Op.getValueType(), Op.getOperand(1), Op.getOperand(2)); diff --git a/llvm/test/CodeGen/AArch64/arm64-vabs.ll b/llvm/test/CodeGen/AArch64/arm64-vabs.ll index 8a0a2dde777..53669a15b9e 100644 --- a/llvm/test/CodeGen/AArch64/arm64-vabs.ll +++ b/llvm/test/CodeGen/AArch64/arm64-vabs.ll @@ -542,8 +542,7 @@ define <1 x i64> @abs_1d(<1 x i64> %A) nounwind { define i64 @abs_1d_honestly(i64 %A) nounwind { ; CHECK-LABEL: abs_1d_honestly: -; CHECK: cmp x0, #0 -; CHECK-NEXT: cneg x0, x0, mi +; CHECK: abs d0, d0 %abs = call i64 @llvm.aarch64.neon.abs.i64(i64 %A) ret i64 %abs } |