From 5bbe6121c3becd127b30a463b52b0d65f1df5baa Mon Sep 17 00:00:00 2001 From: Hao Liu Date: Tue, 29 Apr 2014 07:51:19 +0000 Subject: [PATCH] [ARM64]Fix a bug about incorrect operand order in an EXT instruction, which is introduced by r207485. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207500 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM64/ARM64ISelLowering.cpp | 12 +++++++--- .../ARM64/2014-04-29-EXT-undef-mask.ll | 23 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/ARM64/2014-04-29-EXT-undef-mask.ll diff --git a/lib/Target/ARM64/ARM64ISelLowering.cpp b/lib/Target/ARM64/ARM64ISelLowering.cpp index a832bd044a4..502ff212bee 100644 --- a/lib/Target/ARM64/ARM64ISelLowering.cpp +++ b/lib/Target/ARM64/ARM64ISelLowering.cpp @@ -4001,13 +4001,19 @@ static bool isEXTMask(ArrayRef M, EVT VT, bool &ReverseEXT, // value of the first element. // E.g. <-1, -1, 3, ...> is treated as <1, 2, 3, ...>. // <-1, -1, 0, 1, ...> is treated as . IDX is - // equal to the ExpectedElt. For this case, ExpectedElt is (NumElts*2 - 2). + // equal to the ExpectedElt. Imm = (M[0] >= 0) ? static_cast(M[0]) : ExpectedElt.getZExtValue(); - // Adjust the index value if the source operands will be swapped. - if (Imm >= NumElts) { + // If no beginning UNDEFs, do swap when M[0] >= NumElts. + if (M[0] >= 0 && Imm >= NumElts) { ReverseEXT = true; Imm -= NumElts; + } else if (M[0] < 0) { + // Only do swap when beginning UNDEFs more than the first real element, + if (*FirstRealElt < FirstRealElt - M.begin()) + ReverseEXT = true; + if (Imm >= NumElts) + Imm -= NumElts; } return true; diff --git a/test/CodeGen/ARM64/2014-04-29-EXT-undef-mask.ll b/test/CodeGen/ARM64/2014-04-29-EXT-undef-mask.ll new file mode 100644 index 00000000000..b0ab9fda22d --- /dev/null +++ b/test/CodeGen/ARM64/2014-04-29-EXT-undef-mask.ll @@ -0,0 +1,23 @@ +; RUN: llc < %s -O0 -march=arm64 -arm64-neon-syntax=apple | FileCheck %s + +; The following 2 test cases test shufflevector with beginning UNDEF mask. +define <8 x i16> @test_vext_undef_traverse(<8 x i16> %in) { +;CHECK-LABEL: test_vext_undef_traverse: +;CHECK: {{ext.16b.*v0, #4}} + %vext = shufflevector <8 x i16> , <8 x i16> %in, <8 x i32> + ret <8 x i16> %vext +} + +define <8 x i16> @test_vext_undef_traverse2(<8 x i16> %in) { +;CHECK-LABEL: test_vext_undef_traverse2: +;CHECK: {{ext.16b.*v0, #6}} + %vext = shufflevector <8 x i16> %in, <8 x i16> , <8 x i32> + ret <8 x i16> %vext +} + +define <8 x i8> @test_vext_undef_traverse3(<8 x i8> %in) { +;CHECK-LABEL: test_vext_undef_traverse3: +;CHECK: {{ext.8b.*v0, #6}} + %vext = shufflevector <8 x i8> %in, <8 x i8> , <8 x i32> + ret <8 x i8> %vext +}