]> granicus.if.org Git - llvm/commitdiff
Merging r293259:
authorHans Wennborg <hans@hanshq.net>
Fri, 27 Jan 2017 17:13:59 +0000 (17:13 +0000)
committerHans Wennborg <hans@hanshq.net>
Fri, 27 Jan 2017 17:13:59 +0000 (17:13 +0000)
------------------------------------------------------------------------
r293259 | compnerd | 2017-01-26 19:41:53 -0800 (Thu, 26 Jan 2017) | 11 lines

ARM: fix vectorized division on WoA

The Windows on ARM target uses custom division for normal division as
the backend needs to insert division-by-zero checks.  However, it is
designed to only handle non-vectorized division.  ARM has custom
lowering for vectorized division as that can avoid loading registers
with the values and invoke a division routine for each one, preferring
to lower using NEON instructions.  Fall back to the custom lowering for
the NEON instructions if we encounter a vectorized division.

Resolves PR31778!
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_40@293306 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp
test/CodeGen/ARM/neon_div.ll

index fb4c689bcb5981f72144550672d1f74b8356bf2d..1606c157646571ccb0a36e75a32f82c4ac6c0232 100644 (file)
@@ -7571,11 +7571,11 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
   case ISD::FLT_ROUNDS_:   return LowerFLT_ROUNDS_(Op, DAG);
   case ISD::MUL:           return LowerMUL(Op, DAG);
   case ISD::SDIV:
-    if (Subtarget->isTargetWindows())
+    if (Subtarget->isTargetWindows() && !Op.getValueType().isVector())
       return LowerDIV_Windows(Op, DAG, /* Signed */ true);
     return LowerSDIV(Op, DAG);
   case ISD::UDIV:
-    if (Subtarget->isTargetWindows())
+    if (Subtarget->isTargetWindows() && !Op.getValueType().isVector())
       return LowerDIV_Windows(Op, DAG, /* Signed */ false);
     return LowerUDIV(Op, DAG);
   case ISD::ADDC:
index e185c2a8afbcda42bb06b633c8bb550f35a91698..23b626e0ce51615dbb09efa6cf9fe6e36a43a80a 100644 (file)
@@ -1,49 +1,58 @@
-; RUN: llc -mtriple=arm-eabi -mattr=+neon -pre-RA-sched=source -disable-post-ra %s -o - \
-; RUN:  | FileCheck %s
+; RUN: llc -mtriple arm-eabi -mattr=+neon -disable-post-ra -pre-RA-sched source %s -o - | FileCheck %s
+; RUN: llc -mtriple thumbv7-windows-itanium -mattr=+neon -disable-post-ra -pre-RA-sched source %s -o - | FileCheck %s
 
 define <8 x i8> @sdivi8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
-;CHECK: vrecpe.f32
-;CHECK: vmovn.i32
-;CHECK: vrecpe.f32
-;CHECK: vmovn.i32
-;CHECK: vmovn.i16
-       %tmp1 = load <8 x i8>, <8 x i8>* %A
-       %tmp2 = load <8 x i8>, <8 x i8>* %B
-       %tmp3 = sdiv <8 x i8> %tmp1, %tmp2
-       ret <8 x i8> %tmp3
+  %tmp1 = load <8 x i8>, <8 x i8>* %A
+  %tmp2 = load <8 x i8>, <8 x i8>* %B
+  %tmp3 = sdiv <8 x i8> %tmp1, %tmp2
+  ret <8 x i8> %tmp3
 }
 
+; CHECK-LABEL: sdivi8:
+; CHECK: vrecpe.f32
+; CHECK: vmovn.i32
+; CHECK: vrecpe.f32
+; CHECK: vmovn.i32
+; CHECK: vmovn.i16
+
 define <8 x i8> @udivi8(<8 x i8>* %A, <8 x i8>* %B) nounwind {
-;CHECK: vrecpe.f32
-;CHECK: vrecps.f32
-;CHECK: vmovn.i32
-;CHECK: vrecpe.f32
-;CHECK: vrecps.f32
-;CHECK: vmovn.i32
-;CHECK: vqmovun.s16
-       %tmp1 = load <8 x i8>, <8 x i8>* %A
-       %tmp2 = load <8 x i8>, <8 x i8>* %B
-       %tmp3 = udiv <8 x i8> %tmp1, %tmp2
-       ret <8 x i8> %tmp3
+  %tmp1 = load <8 x i8>, <8 x i8>* %A
+  %tmp2 = load <8 x i8>, <8 x i8>* %B
+  %tmp3 = udiv <8 x i8> %tmp1, %tmp2
+  ret <8 x i8> %tmp3
 }
 
+; CHECK-LABEL: udivi8:
+; CHECK: vrecpe.f32
+; CHECK: vrecps.f32
+; CHECK: vmovn.i32
+; CHECK: vrecpe.f32
+; CHECK: vrecps.f32
+; CHECK: vmovn.i32
+; CHECK: vqmovun.s16
+
 define <4 x i16> @sdivi16(<4 x i16>* %A, <4 x i16>* %B) nounwind {
-;CHECK: vrecpe.f32
-;CHECK: vrecps.f32
-;CHECK: vmovn.i32
-       %tmp1 = load <4 x i16>, <4 x i16>* %A
-       %tmp2 = load <4 x i16>, <4 x i16>* %B
-       %tmp3 = sdiv <4 x i16> %tmp1, %tmp2
-       ret <4 x i16> %tmp3
+  %tmp1 = load <4 x i16>, <4 x i16>* %A
+  %tmp2 = load <4 x i16>, <4 x i16>* %B
+  %tmp3 = sdiv <4 x i16> %tmp1, %tmp2
+  ret <4 x i16> %tmp3
 }
 
+; CHECK-LABEL: sdivi16:
+; CHECK: vrecpe.f32
+; CHECK: vrecps.f32
+; CHECK: vmovn.i32
+
 define <4 x i16> @udivi16(<4 x i16>* %A, <4 x i16>* %B) nounwind {
-;CHECK: vrecpe.f32
-;CHECK: vrecps.f32
-;CHECK: vrecps.f32
-;CHECK: vmovn.i32
-       %tmp1 = load <4 x i16>, <4 x i16>* %A
-       %tmp2 = load <4 x i16>, <4 x i16>* %B
-       %tmp3 = udiv <4 x i16> %tmp1, %tmp2
-       ret <4 x i16> %tmp3
+  %tmp1 = load <4 x i16>, <4 x i16>* %A
+  %tmp2 = load <4 x i16>, <4 x i16>* %B
+  %tmp3 = udiv <4 x i16> %tmp1, %tmp2
+  ret <4 x i16> %tmp3
 }
+
+; CHECK-LABEL: udivi16:
+; CHECK: vrecpe.f32
+; CHECK: vrecps.f32
+; CHECK: vrecps.f32
+; CHECK: vmovn.i32
+