OSDN Git Service

[AArch64] Explicitly use v1i64 type for llvm.aarch64.neon.abs.i64 .
authorEli Friedman <efriedma@codeaurora.org>
Tue, 15 Jan 2019 00:15:24 +0000 (00:15 +0000)
committerEli Friedman <efriedma@codeaurora.org>
Tue, 15 Jan 2019 00:15:24 +0000 (00:15 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351141 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64ISelLowering.cpp
test/CodeGen/AArch64/arm64-vabs.ll

index 0e5e6d4..e01ca14 100644 (file)
@@ -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));
index 8a0a2dd..53669a1 100644 (file)
@@ -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
 }