<div dir="ltr"><span style="font-family:monospace,monospace">Hello Mikhail,<br><br>This commit broke one of our builders:<br><a href="http://lab.llvm.org:8011/builders/lld-perf-testsuite/builds/880">http://lab.llvm.org:8011/builders/lld-perf-testsuite/builds/880</a><br><br>
<span style="font-family:monospace,monospace">Please have a look?<br><br>Thanks<br><br>Galina</span>

<br><br><br>. . . <br>FAILED: /usr/bin/c++   -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Ilib/Target/ARM/AsmParser -I/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/lib/Target/ARM/AsmParser -I/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/lib/Target/ARM -Ilib/Target/ARM -Iinclude -I/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/include -fvisibility-inlines-hidden -Werror -Werror=date-time -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O3    -UNDEBUG  -fno-exceptions -fno-rtti -MMD -MT lib/Target/ARM/AsmParser/CMakeFiles/LLVMARMAsmParser.dir/ARMAsmParser.cpp.o -MF lib/Target/ARM/AsmParser/CMakeFiles/LLVMARMAsmParser.dir/ARMAsmParser.cpp.o.d -o lib/Target/ARM/AsmParser/CMakeFiles/LLVMARMAsmParser.dir/ARMAsmParser.cpp.o -c /home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp<br>In file included from /usr/include/c++/5/cassert:43:0,<br>                 from /home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp:57:<br>/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp: In member function ‘bool {anonymous}::ARMOperand::isNEONReplicate(unsigned int, unsigned int, bool, bool) const’:<br>/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp:1873:53: error: suggest parentheses around ‘&&’ within ‘||’ [-Werror=parentheses]<br>     assert(Width == 8 || Width == 16 || Width == 32 && "Invalid element width");<br>                                                     ^<br>/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp: In static member function ‘static void {anonymous}::ARMOperand::checkNeonReplicateArgs(unsigned int, unsigned int)’:<br>/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp:1910:53: error: suggest parentheses around ‘&&’ within ‘||’ [-Werror=parentheses]<br>     assert(FromW == 8 || FromW == 16 || FromW == 32 && "Invalid source width");<br>                                                     ^<br>/home/buildslave/slave_as-bldslv8/lld-perf-testsuite/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp:1911:48: error: suggest parentheses around ‘&&’ within ‘||’ [-Werror=parentheses]<br>     assert(ToW == 16 || ToW == 32 || ToW == 64 && "Invalid destination width");<br>                                                ^<br>cc1plus: all warnings being treated as errors<br><br><br></span><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 16, 2018 at 7:10 AM, Mikhail Maltsev via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: miyuki<br>
Date: Fri Mar 16 07:10:56 2018<br>
New Revision: 327709<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=327709&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=327709&view=rev</a><br>
Log:<br>
[ARM] Convert more invalid NEON immediate loads<br>
<br>
Summary:<br>
Currently the LLVM MC assembler is able to convert e.g.<br>
<br>
  vmov.i32 d0, #0xabababab<br>
<br>
(which is technically invalid) into a valid instruction<br>
<br>
  vmov.i8 d0, #0xab<br>
<br>
this patch adds support for vmov.i64 and for cases with the resulting<br>
load types other than i8, e.g.:<br>
<br>
  vmov.i32 d0, #0xab00ab00 -><br>
  vmov.i16 d0, #0xab00<br>
<br>
Reviewers: olista01, rengolin<br>
<br>
Reviewed By: rengolin<br>
<br>
Subscribers: rengolin, javed.absar, kristof.beyls, rogfer01, llvm-commits<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D44467" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D44467</a><br>
<br>
Added:<br>
    llvm/trunk/test/MC/ARM/vmov-<wbr>vmvn-replicate.s<br>
Removed:<br>
    llvm/trunk/test/MC/ARM/vmov-<wbr>vmvn-byte-replicate.s<br>
Modified:<br>
    llvm/trunk/lib/Target/ARM/<wbr>ARMInstrNEON.td<br>
    llvm/trunk/lib/Target/ARM/<wbr>AsmParser/ARMAsmParser.cpp<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/<wbr>ARMInstrNEON.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=327709&r1=327708&r2=327709&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>ARM/ARMInstrNEON.td?rev=<wbr>327709&r1=327708&r2=327709&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/ARM/<wbr>ARMInstrNEON.td (original)<br>
+++ llvm/trunk/lib/Target/ARM/<wbr>ARMInstrNEON.td Fri Mar 16 07:10:56 2018<br>
@@ -48,46 +48,28 @@ def nImmVMOVI32 : Operand<i32> {<br>
   let ParserMatchClass = nImmVMOVI32AsmOperand;<br>
 }<br>
<br>
-def nImmVMOVI16AsmOperandByteRepli<wbr>cate :<br>
-  AsmOperandClass {<br>
-  let Name = "NEONi16vmovByteReplicate";<br>
-  let PredicateMethod = "isNEONi16ByteReplicate";<br>
-  let RenderMethod = "<wbr>addNEONvmovByteReplicateOperan<wbr>ds";<br>
-}<br>
-def nImmVMOVI32AsmOperandByteRepli<wbr>cate :<br>
-  AsmOperandClass {<br>
-  let Name = "NEONi32vmovByteReplicate";<br>
-  let PredicateMethod = "isNEONi32ByteReplicate";<br>
-  let RenderMethod = "<wbr>addNEONvmovByteReplicateOperan<wbr>ds";<br>
-}<br>
-def nImmVMVNI16AsmOperandByteRepli<wbr>cate :<br>
-  AsmOperandClass {<br>
-  let Name = "NEONi16invByteReplicate";<br>
-  let PredicateMethod = "isNEONi16ByteReplicate";<br>
-  let RenderMethod = "<wbr>addNEONinvByteReplicateOperand<wbr>s";<br>
-}<br>
-def nImmVMVNI32AsmOperandByteRepli<wbr>cate :<br>
-  AsmOperandClass {<br>
-  let Name = "NEONi32invByteReplicate";<br>
-  let PredicateMethod = "isNEONi32ByteReplicate";<br>
-  let RenderMethod = "<wbr>addNEONinvByteReplicateOperand<wbr>s";<br>
+class nImmVMOVIAsmOperandReplicate<<wbr>ValueType From, ValueType To><br>
+  : AsmOperandClass {<br>
+  let Name = "NEONi" # To.Size # "vmovi" # From.Size # "Replicate";<br>
+  let PredicateMethod = "isNEONmovReplicate<" # From.Size # ", " # To.Size # ">";<br>
+  let RenderMethod = "addNEONvmovi" # From.Size # "ReplicateOperands";<br>
 }<br>
<br>
-def nImmVMOVI16ByteReplicate : Operand<i32> {<br>
-  let PrintMethod = "printNEONModImmOperand";<br>
-  let ParserMatchClass = nImmVMOVI16AsmOperandByteRepli<wbr>cate;<br>
-}<br>
-def nImmVMOVI32ByteReplicate : Operand<i32> {<br>
-  let PrintMethod = "printNEONModImmOperand";<br>
-  let ParserMatchClass = nImmVMOVI32AsmOperandByteRepli<wbr>cate;<br>
+class nImmVINVIAsmOperandReplicate<<wbr>ValueType From, ValueType To><br>
+  : AsmOperandClass {<br>
+  let Name = "NEONi" # To.Size # "invi" # From.Size # "Replicate";<br>
+  let PredicateMethod = "isNEONinvReplicate<" # From.Size # ", " # To.Size # ">";<br>
+  let RenderMethod = "addNEONinvi" # From.Size # "ReplicateOperands";<br>
 }<br>
-def nImmVMVNI16ByteReplicate : Operand<i32> {<br>
+<br>
+class nImmVMOVIReplicate<ValueType From, ValueType To> : Operand<i32> {<br>
   let PrintMethod = "printNEONModImmOperand";<br>
-  let ParserMatchClass = nImmVMVNI16AsmOperandByteRepli<wbr>cate;<br>
+  let ParserMatchClass = nImmVMOVIAsmOperandReplicate<<wbr>From, To>;<br>
 }<br>
-def nImmVMVNI32ByteReplicate : Operand<i32> {<br>
+<br>
+class nImmVINVIReplicate<ValueType From, ValueType To> : Operand<i32> {<br>
   let PrintMethod = "printNEONModImmOperand";<br>
-  let ParserMatchClass = nImmVMVNI32AsmOperandByteRepli<wbr>cate;<br>
+  let ParserMatchClass = nImmVINVIAsmOperandReplicate<<wbr>From, To>;<br>
 }<br>
<br>
 def nImmVMOVI32NegAsmOperand : AsmOperandClass { let Name = "NEONi32vmovNeg"; }<br>
@@ -5933,34 +5915,57 @@ def VMOVv4f32 : N1ModImm<1, 0b000, 0b111<br>
 } // isReMaterializable, isAsCheapAsAMove<br>
<br>
 // Add support for bytes replication feature, so it could be GAS compatible.<br>
-// E.g. instructions below:<br>
-// "vmov.i32 d0, 0xffffffff"<br>
-// "vmov.i32 d0, 0xabababab"<br>
-// "vmov.i16 d0, 0xabab"<br>
-// are incorrect, but we could deal with such cases.<br>
-// For last two instructions, for example, it should emit:<br>
-// "vmov.i8 d0, 0xab"<br>
-def : NEONInstAlias<"vmov${p}.i16 $Vd, $Vm",<br>
-                    (VMOVv8i8 DPR:$Vd, nImmVMOVI16ByteReplicate:$Vm, pred:$p)>;<br>
-def : NEONInstAlias<"vmov${p}.i32 $Vd, $Vm",<br>
-                    (VMOVv8i8 DPR:$Vd, nImmVMOVI32ByteReplicate:$Vm, pred:$p)>;<br>
-def : NEONInstAlias<"vmov${p}.i16 $Vd, $Vm",<br>
-                    (VMOVv16i8 QPR:$Vd, nImmVMOVI16ByteReplicate:$Vm, pred:$p)>;<br>
-def : NEONInstAlias<"vmov${p}.i32 $Vd, $Vm",<br>
-                    (VMOVv16i8 QPR:$Vd, nImmVMOVI32ByteReplicate:$Vm, pred:$p)>;<br>
-<br>
-// Also add same support for VMVN instructions. So instruction:<br>
-// "vmvn.i32 d0, 0xabababab"<br>
-// actually means:<br>
-// "vmov.i8 d0, 0x54"<br>
-def : NEONInstAlias<"vmvn${p}.i16 $Vd, $Vm",<br>
-                    (VMOVv8i8 DPR:$Vd, nImmVMVNI16ByteReplicate:$Vm, pred:$p)>;<br>
-def : NEONInstAlias<"vmvn${p}.i32 $Vd, $Vm",<br>
-                    (VMOVv8i8 DPR:$Vd, nImmVMVNI32ByteReplicate:$Vm, pred:$p)>;<br>
-def : NEONInstAlias<"vmvn${p}.i16 $Vd, $Vm",<br>
-                    (VMOVv16i8 QPR:$Vd, nImmVMVNI16ByteReplicate:$Vm, pred:$p)>;<br>
-def : NEONInstAlias<"vmvn${p}.i32 $Vd, $Vm",<br>
-                    (VMOVv16i8 QPR:$Vd, nImmVMVNI32ByteReplicate:$Vm, pred:$p)>;<br>
+multiclass NEONImmReplicateI8InstAlias<<wbr>ValueType To> {<br>
+  // E.g. instructions below:<br>
+  // "vmov.i32 d0, #0xffffffff"<br>
+  // "vmov.i32 d0, #0xabababab"<br>
+  // "vmov.i16 d0, #0xabab"<br>
+  // are incorrect, but we could deal with such cases.<br>
+  // For last two instructions, for example, it should emit:<br>
+  // "vmov.i8 d0, #0xab"<br>
+  def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",<br>
+                      (VMOVv8i8 DPR:$Vd, nImmVMOVIReplicate<i8, To>:$Vm, pred:$p)>;<br>
+  def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",<br>
+                      (VMOVv16i8 QPR:$Vd, nImmVMOVIReplicate<i8, To>:$Vm, pred:$p)>;<br>
+  // Also add same support for VMVN instructions. So instruction:<br>
+  // "vmvn.i32 d0, #0xabababab"<br>
+  // actually means:<br>
+  // "vmov.i8 d0, #0x54"<br>
+  def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",<br>
+                      (VMOVv8i8 DPR:$Vd, nImmVINVIReplicate<i8, To>:$Vm, pred:$p)>;<br>
+  def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",<br>
+                      (VMOVv16i8 QPR:$Vd, nImmVINVIReplicate<i8, To>:$Vm, pred:$p)>;<br>
+}<br>
+<br>
+defm : NEONImmReplicateI8InstAlias<<wbr>i16>;<br>
+defm : NEONImmReplicateI8InstAlias<<wbr>i32>;<br>
+defm : NEONImmReplicateI8InstAlias<<wbr>i64>;<br>
+<br>
+// Similar to above for types other than i8, e.g.:<br>
+// "vmov.i32 d0, #0xab00ab00" -> "vmov.i16 d0, #0xab00"<br>
+// "vmvn.i64 q0, #0xab000000ab000000" -> "vmvn.i32 q0, #0xab000000"<br>
+// In this case we do not canonicalize VMVN to VMOV<br>
+multiclass NEONImmReplicateInstAlias<<wbr>ValueType From, NeonI V8, NeonI V16,<br>
+                                     NeonI NV8, NeonI NV16, ValueType To> {<br>
+  def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",<br>
+                      (V8 DPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;<br>
+  def : NEONInstAlias<"vmov${p}.i" # To.Size # " $Vd, $Vm",<br>
+                      (V16 QPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;<br>
+  def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",<br>
+                      (NV8 DPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;<br>
+  def : NEONInstAlias<"vmvn${p}.i" # To.Size # " $Vd, $Vm",<br>
+                      (NV16 QPR:$Vd, nImmVMOVIReplicate<From, To>:$Vm, pred:$p)>;<br>
+}<br>
+<br>
+defm : NEONImmReplicateInstAlias<i16, VMOVv4i16, VMOVv8i16,<br>
+                                      VMVNv4i16, VMVNv8i16, i32>;<br>
+defm : NEONImmReplicateInstAlias<i16, VMOVv4i16, VMOVv8i16,<br>
+                                      VMVNv4i16, VMVNv8i16, i64>;<br>
+defm : NEONImmReplicateInstAlias<i32, VMOVv2i32, VMOVv4i32,<br>
+                                      VMVNv2i32, VMVNv4i32, i64>;<br>
+// TODO: add "VMOV <-> VMVN" conversion for cases like<br>
+// "vmov.i32 d0, #0xffaaffaa" -> "vmvn.i16 d0, #0x55"<br>
+// "vmvn.i32 d0, #0xaaffaaff" -> "vmov.i16 d0, #0xff00"<br>
<br>
 // On some CPUs the two instructions "vmov.i32 dD, #0" and "vmov.i32 qD, #0"<br>
 // require zero cycles to execute so they should be used wherever possible for<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/<wbr>AsmParser/ARMAsmParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=327709&r1=327708&r2=327709&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>ARM/AsmParser/ARMAsmParser.<wbr>cpp?rev=327709&r1=327708&r2=<wbr>327709&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/ARM/<wbr>AsmParser/ARMAsmParser.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/<wbr>AsmParser/ARMAsmParser.cpp Fri Mar 16 07:10:56 2018<br>
@@ -1857,7 +1857,22 @@ public:<br>
     return ARM_AM::isNEONi32splat(~Value)<wbr>;<br>
   }<br>
<br>
-  bool isNEONByteReplicate(unsigned NumBytes) const {<br>
+  static bool isValidNEONi32vmovImm(int64_t Value) {<br>
+    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,<br>
+    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.<br>
+    return ((Value & 0xffffffffffffff00) == 0) ||<br>
+           ((Value & 0xffffffffffff00ff) == 0) ||<br>
+           ((Value & 0xffffffffff00ffff) == 0) ||<br>
+           ((Value & 0xffffffff00ffffff) == 0) ||<br>
+           ((Value & 0xffffffffffff00ff) == 0xff) ||<br>
+           ((Value & 0xffffffffff00ffff) == 0xffff);<br>
+  }<br>
+<br>
+  bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv,<br>
+                       bool AllowMinusOne) const {<br>
+    assert(Width == 8 || Width == 16 || Width == 32 && "Invalid element width");<br>
+    assert(NumElems * Width <= 64 && "Invalid result width");<br>
+<br>
     if (!isImm())<br>
       return false;<br>
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(<wbr>getImm());<br>
@@ -1867,28 +1882,47 @@ public:<br>
     int64_t Value = CE->getValue();<br>
     if (!Value)<br>
       return false; // Don't bother with zero.<br>
+    if (Inv)<br>
+      Value = ~Value;<br>
<br>
-    unsigned char B = Value & 0xff;<br>
-    for (unsigned i = 1; i < NumBytes; ++i) {<br>
-      Value >>= 8;<br>
-      if ((Value & 0xff) != B)<br>
+    uint64_t Mask = (1ull << Width) - 1;<br>
+    uint64_t Elem = Value & Mask;<br>
+    if (!AllowMinusOne && Elem == Mask)<br>
+      return false;<br>
+    if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)<br>
+      return false;<br>
+    if (Width == 32 && !isValidNEONi32vmovImm(Elem))<br>
+      return false;<br>
+<br>
+    for (unsigned i = 1; i < NumElems; ++i) {<br>
+      Value >>= Width;<br>
+      if ((Value & Mask) != Elem)<br>
         return false;<br>
     }<br>
     return true;<br>
   }<br>
<br>
-  bool isNEONi16ByteReplicate() const { return isNEONByteReplicate(2); }<br>
-  bool isNEONi32ByteReplicate() const { return isNEONByteReplicate(4); }<br>
+  bool isNEONByteReplicate(unsigned NumBytes) const {<br>
+    return isNEONReplicate(8, NumBytes, false, true);<br>
+  }<br>
<br>
-  static bool isValidNEONi32vmovImm(int64_t Value) {<br>
-    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,<br>
-    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.<br>
-    return ((Value & 0xffffffffffffff00) == 0) ||<br>
-           ((Value & 0xffffffffffff00ff) == 0) ||<br>
-           ((Value & 0xffffffffff00ffff) == 0) ||<br>
-           ((Value & 0xffffffff00ffffff) == 0) ||<br>
-           ((Value & 0xffffffffffff00ff) == 0xff) ||<br>
-           ((Value & 0xffffffffff00ffff) == 0xffff);<br>
+  static void checkNeonReplicateArgs(<wbr>unsigned FromW, unsigned ToW) {<br>
+    assert(FromW == 8 || FromW == 16 || FromW == 32 && "Invalid source width");<br>
+    assert(ToW == 16 || ToW == 32 || ToW == 64 && "Invalid destination width");<br>
+    assert(FromW < ToW && "ToW is not less than FromW");<br>
+  }<br>
+<br>
+  template<unsigned FromW, unsigned ToW><br>
+  bool isNEONmovReplicate() const {<br>
+    checkNeonReplicateArgs(FromW, ToW);<br>
+    bool AllowMinusOne = ToW != 64;<br>
+    return isNEONReplicate(FromW, ToW / FromW, false, AllowMinusOne);<br>
+  }<br>
+<br>
+  template<unsigned FromW, unsigned ToW><br>
+  bool isNEONinvReplicate() const {<br>
+    checkNeonReplicateArgs(FromW, ToW);<br>
+    return isNEONReplicate(FromW, ToW / FromW, true, true);<br>
   }<br>
<br>
   bool isNEONi32vmov() const {<br>
@@ -2726,62 +2760,87 @@ public:<br>
     Inst.addOperand(MCOperand::<wbr>createImm(Value));<br>
   }<br>
<br>
-  void addNEONinvByteReplicateOperand<wbr>s(MCInst &Inst, unsigned N) const {<br>
-    assert(N == 1 && "Invalid number of operands!");<br>
+  void addNEONi8ReplicateOperands(<wbr>MCInst &Inst, bool Inv) const {<br>
     // The immediate encodes the type of constant as well as the value.<br>
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(<wbr>getImm());<br>
-    unsigned Value = CE->getValue();<br>
     assert((Inst.getOpcode() == ARM::VMOVv8i8 ||<br>
             Inst.getOpcode() == ARM::VMOVv16i8) &&<br>
-           "All vmvn instructions that wants to replicate non-zero byte "<br>
-           "always must be replaced with VMOVv8i8 or VMOVv16i8.");<br>
-    unsigned B = ((~Value) & 0xff);<br>
+          "All instructions that wants to replicate non-zero byte "<br>
+          "always must be replaced with VMOVv8i8 or VMOVv16i8.");<br>
+    unsigned Value = CE->getValue();<br>
+    if (Inv)<br>
+      Value = ~Value;<br>
+    unsigned B = Value & 0xff;<br>
     B |= 0xe00; // cmode = 0b1110<br>
     Inst.addOperand(MCOperand::<wbr>createImm(B));<br>
   }<br>
<br>
-  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {<br>
+  void addNEONinvi8ReplicateOperands(<wbr>MCInst &Inst, unsigned N) const {<br>
     assert(N == 1 && "Invalid number of operands!");<br>
-    // The immediate encodes the type of constant as well as the value.<br>
-    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(<wbr>getImm());<br>
-    unsigned Value = CE->getValue();<br>
+    addNEONi8ReplicateOperands(<wbr>Inst, true);<br>
+  }<br>
+<br>
+  static unsigned encodeNeonVMOVImmediate(<wbr>unsigned Value) {<br>
     if (Value >= 256 && Value <= 0xffff)<br>
       Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);<br>
     else if (Value > 0xffff && Value <= 0xffffff)<br>
       Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);<br>
     else if (Value > 0xffffff)<br>
       Value = (Value >> 24) | 0x600;<br>
-    Inst.addOperand(MCOperand::<wbr>createImm(Value));<br>
+    return Value;<br>
   }<br>
<br>
-  void addNEONvmovByteReplicateOperan<wbr>ds(MCInst &Inst, unsigned N) const {<br>
+  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {<br>
     assert(N == 1 && "Invalid number of operands!");<br>
     // The immediate encodes the type of constant as well as the value.<br>
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(<wbr>getImm());<br>
-    unsigned Value = CE->getValue();<br>
-    assert((Inst.getOpcode() == ARM::VMOVv8i8 ||<br>
-            Inst.getOpcode() == ARM::VMOVv16i8) &&<br>
-           "All instructions that wants to replicate non-zero byte "<br>
-           "always must be replaced with VMOVv8i8 or VMOVv16i8.");<br>
-    unsigned B = Value & 0xff;<br>
-    B |= 0xe00; // cmode = 0b1110<br>
-    Inst.addOperand(MCOperand::<wbr>createImm(B));<br>
+    unsigned Value = encodeNeonVMOVImmediate(CE-><wbr>getValue());<br>
+    Inst.addOperand(MCOperand::<wbr>createImm(Value));<br>
+  }<br>
+<br>
+  void addNEONvmovi8ReplicateOperands<wbr>(MCInst &Inst, unsigned N) const {<br>
+    assert(N == 1 && "Invalid number of operands!");<br>
+    addNEONi8ReplicateOperands(<wbr>Inst, false);<br>
+  }<br>
+<br>
+  void addNEONvmovi16ReplicateOperand<wbr>s(MCInst &Inst, unsigned N) const {<br>
+    assert(N == 1 && "Invalid number of operands!");<br>
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(<wbr>getImm());<br>
+    assert((Inst.getOpcode() == ARM::VMOVv4i16 ||<br>
+            Inst.getOpcode() == ARM::VMOVv8i16 ||<br>
+            Inst.getOpcode() == ARM::VMVNv4i16 ||<br>
+            Inst.getOpcode() == ARM::VMVNv8i16) &&<br>
+          "All instructions that want to replicate non-zero half-word "<br>
+          "always must be replaced with V{MOV,MVN}v{4,8}i16.");<br>
+    uint64_t Value = CE->getValue();<br>
+    unsigned Elem = Value & 0xffff;<br>
+    if (Elem >= 256)<br>
+      Elem = (Elem >> 8) | 0x200;<br>
+    Inst.addOperand(MCOperand::<wbr>createImm(Elem));<br>
   }<br>
<br>
   void addNEONi32vmovNegOperands(<wbr>MCInst &Inst, unsigned N) const {<br>
     assert(N == 1 && "Invalid number of operands!");<br>
     // The immediate encodes the type of constant as well as the value.<br>
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(<wbr>getImm());<br>
-    unsigned Value = ~CE->getValue();<br>
-    if (Value >= 256 && Value <= 0xffff)<br>
-      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);<br>
-    else if (Value > 0xffff && Value <= 0xffffff)<br>
-      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);<br>
-    else if (Value > 0xffffff)<br>
-      Value = (Value >> 24) | 0x600;<br>
+    unsigned Value = encodeNeonVMOVImmediate(~CE-><wbr>getValue());<br>
     Inst.addOperand(MCOperand::<wbr>createImm(Value));<br>
   }<br>
<br>
+  void addNEONvmovi32ReplicateOperand<wbr>s(MCInst &Inst, unsigned N) const {<br>
+    assert(N == 1 && "Invalid number of operands!");<br>
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(<wbr>getImm());<br>
+    assert((Inst.getOpcode() == ARM::VMOVv2i32 ||<br>
+            Inst.getOpcode() == ARM::VMOVv4i32 ||<br>
+            Inst.getOpcode() == ARM::VMVNv2i32 ||<br>
+            Inst.getOpcode() == ARM::VMVNv4i32) &&<br>
+          "All instructions that want to replicate non-zero word "<br>
+          "always must be replaced with V{MOV,MVN}v{2,4}i32.");<br>
+    uint64_t Value = CE->getValue();<br>
+    unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);<br>
+    Inst.addOperand(MCOperand::<wbr>createImm(Elem));<br>
+  }<br>
+<br>
   void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {<br>
     assert(N == 1 && "Invalid number of operands!");<br>
     // The immediate encodes the type of constant as well as the value.<br>
<br>
Removed: llvm/trunk/test/MC/ARM/vmov-<wbr>vmvn-byte-replicate.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/vmov-vmvn-byte-replicate.s?rev=327708&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/MC/<wbr>ARM/vmov-vmvn-byte-replicate.<wbr>s?rev=327708&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/MC/ARM/vmov-<wbr>vmvn-byte-replicate.s (original)<br>
+++ llvm/trunk/test/MC/ARM/vmov-<wbr>vmvn-byte-replicate.s (removed)<br>
@@ -1,31 +0,0 @@<br>
-@ PR18921, "vmov" part.<br>
-@ RUN: llvm-mc -triple=armv7-linux-gnueabi -show-encoding < %s | FileCheck %s<br>
-.text<br>
-<br>
-@ CHECK: vmov.i8 d2, #0xff @ encoding: [0x1f,0x2e,0x87,0xf3]<br>
-@ CHECK: vmov.i8 q2, #0xff @ encoding: [0x5f,0x4e,0x87,0xf3]<br>
-@ CHECK: vmov.i8 d2, #0xab @ encoding: [0x1b,0x2e,0x82,0xf3]<br>
-@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]<br>
-@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]<br>
-@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]<br>
-<br>
-@ CHECK: vmov.i8 d2, #0x0  @ encoding: [0x10,0x2e,0x80,0xf2]<br>
-@ CHECK: vmov.i8 q2, #0x0  @ encoding: [0x50,0x4e,0x80,0xf2]<br>
-@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]<br>
-@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]<br>
-@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]<br>
-@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]<br>
-<br>
-        vmov.i32        d2, #0xffffffff<br>
-        vmov.i32        q2, #0xffffffff<br>
-        vmov.i32        d2, #0xabababab<br>
-        vmov.i32        q2, #0xabababab<br>
-        vmov.i16        q2, #0xabab<br>
-        vmov.i16        q2, #0xabab<br>
-<br>
-        vmvn.i32        d2, #0xffffffff<br>
-        vmvn.i32        q2, #0xffffffff<br>
-        vmvn.i32        d2, #0xabababab<br>
-        vmvn.i32        q2, #0xabababab<br>
-        vmvn.i16        d2, #0xabab<br>
-        vmvn.i16        q2, #0xabab<br>
<br>
Added: llvm/trunk/test/MC/ARM/vmov-<wbr>vmvn-replicate.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/vmov-vmvn-replicate.s?rev=327709&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/MC/<wbr>ARM/vmov-vmvn-replicate.s?rev=<wbr>327709&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/MC/ARM/vmov-<wbr>vmvn-replicate.s (added)<br>
+++ llvm/trunk/test/MC/ARM/vmov-<wbr>vmvn-replicate.s Fri Mar 16 07:10:56 2018<br>
@@ -0,0 +1,102 @@<br>
+@ PR18921, "vmov" part.<br>
+@ RUN: llvm-mc -triple=armv7-linux-gnueabi -show-encoding < %s | FileCheck %s<br>
+.text<br>
+        vmov.i64        d2, #0xffffffffffffffff<br>
+        vmov.i64        q2, #0xffffffffffffffff<br>
+        vmov.i32        d2, #0xffffffff<br>
+        vmov.i32        q2, #0xffffffff<br>
+        vmov.i64        d2, #0xabababababababab<br>
+        vmov.i64        q2, #0xabababababababab<br>
+        vmov.i32        d2, #0xabababab<br>
+        vmov.i32        q2, #0xabababab<br>
+        vmov.i16        q2, #0xabab<br>
+        vmov.i16        q2, #0xabab<br>
+<br>
+@ CHECK: vmov.i64 d2, #0xffffffffffffffff @ encoding: [0x3f,0x2e,0x87,0xf3]<br>
+@ CHECK: vmov.i64 q2, #0xffffffffffffffff @ encoding: [0x7f,0x4e,0x87,0xf3]<br>
+@ CHECK: vmov.i8 d2, #0xff @ encoding: [0x1f,0x2e,0x87,0xf3]<br>
+@ CHECK: vmov.i8 q2, #0xff @ encoding: [0x5f,0x4e,0x87,0xf3]<br>
+@ CHECK: vmov.i8 d2, #0xab @ encoding: [0x1b,0x2e,0x82,0xf3]<br>
+@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]<br>
+@ CHECK: vmov.i8 d2, #0xab @ encoding: [0x1b,0x2e,0x82,0xf3]<br>
+@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]<br>
+@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]<br>
+@ CHECK: vmov.i8 q2, #0xab @ encoding: [0x5b,0x4e,0x82,0xf3]<br>
+<br>
+        vmov.i64        d2, #0x00a500a500a500a5<br>
+        vmov.i64        q2, #0x00a500a500a500a5<br>
+        vmov.i32        d2, #0x00a500a5<br>
+        vmov.i32        q2, #0x00a500a5<br>
+        vmov.i64        d2, #0xa500a500a500a500<br>
+        vmov.i64        q2, #0xa500a500a500a500<br>
+        vmov.i32        d2, #0xa500a500<br>
+        vmov.i32        q2, #0xa500a500<br>
+<br>
+@ CHECK: vmov.i16 d2, #0xa5 @ encoding: [0x15,0x28,0x82,0xf3]<br>
+@ CHECK: vmov.i16 q2, #0xa5 @ encoding: [0x55,0x48,0x82,0xf3]<br>
+@ CHECK: vmov.i16 d2, #0xa5 @ encoding: [0x15,0x28,0x82,0xf3]<br>
+@ CHECK: vmov.i16 q2, #0xa5 @ encoding: [0x55,0x48,0x82,0xf3]<br>
+@ CHECK: vmov.i16 d2, #0xa500 @ encoding: [0x15,0x2a,0x82,0xf3]<br>
+@ CHECK: vmov.i16 q2, #0xa500 @ encoding: [0x55,0x4a,0x82,0xf3]<br>
+@ CHECK: vmov.i16 d2, #0xa500 @ encoding: [0x15,0x2a,0x82,0xf3]<br>
+@ CHECK: vmov.i16 q2, #0xa500 @ encoding: [0x55,0x4a,0x82,0xf3]<br>
+<br>
+        vmov.i64        d2, #0x000000a5000000a5<br>
+        vmov.i64        q2, #0x000000a5000000a5<br>
+        vmov.i64        d2, #0x00a5ffff00a5ffff<br>
+        vmov.i64        q2, #0x00a5ffff00a5ffff<br>
+<br>
+@ CHECK: vmov.i32 d2, #0xa5 @ encoding: [0x15,0x20,0x82,0xf3]<br>
+@ CHECK: vmov.i32 q2, #0xa5 @ encoding: [0x55,0x40,0x82,0xf3]<br>
+@ CHECK: vmov.i32 d2, #0xa5ffff @ encoding: [0x15,0x2d,0x82,0xf3]<br>
+@ CHECK: vmov.i32 q2, #0xa5ffff @ encoding: [0x55,0x4d,0x82,0xf3]<br>
+<br>
+        vmvn.i64        d2, #0xffffffffffffffff<br>
+        vmvn.i64        q2, #0xffffffffffffffff<br>
+        vmvn.i32        d2, #0xffffffff<br>
+        vmvn.i32        q2, #0xffffffff<br>
+        vmvn.i64        d2, #0xabababababababab<br>
+        vmvn.i64        q2, #0xabababababababab<br>
+        vmvn.i32        d2, #0xabababab<br>
+        vmvn.i32        q2, #0xabababab<br>
+        vmvn.i16        d2, #0xabab<br>
+        vmvn.i16        q2, #0xabab<br>
+<br>
+@ CHECK: vmov.i8 d2, #0x0  @ encoding: [0x10,0x2e,0x80,0xf2]<br>
+@ CHECK: vmov.i8 q2, #0x0  @ encoding: [0x50,0x4e,0x80,0xf2]<br>
+@ CHECK: vmov.i8 d2, #0x0  @ encoding: [0x10,0x2e,0x80,0xf2]<br>
+@ CHECK: vmov.i8 q2, #0x0  @ encoding: [0x50,0x4e,0x80,0xf2]<br>
+@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]<br>
+@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]<br>
+@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]<br>
+@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]<br>
+@ CHECK: vmov.i8 d2, #0x54 @ encoding: [0x14,0x2e,0x85,0xf2]<br>
+@ CHECK: vmov.i8 q2, #0x54 @ encoding: [0x54,0x4e,0x85,0xf2]<br>
+<br>
+        vmvn.i64        d2, #0x00a500a500a500a5<br>
+        vmvn.i64        q2, #0x00a500a500a500a5<br>
+        vmvn.i32        d2, #0x00a500a5<br>
+        vmvn.i32        q2, #0x00a500a5<br>
+        vmvn.i64        d2, #0xa500a500a500a500<br>
+        vmvn.i64        q2, #0xa500a500a500a500<br>
+        vmvn.i32        d2, #0xa500a500<br>
+        vmvn.i32        q2, #0xa500a500<br>
+<br>
+@ CHECK: vmvn.i16 d2, #0xa5 @ encoding: [0x35,0x28,0x82,0xf3]<br>
+@ CHECK: vmvn.i16 q2, #0xa5 @ encoding: [0x75,0x48,0x82,0xf3]<br>
+@ CHECK: vmvn.i16 d2, #0xa5 @ encoding: [0x35,0x28,0x82,0xf3]<br>
+@ CHECK: vmvn.i16 q2, #0xa5 @ encoding: [0x75,0x48,0x82,0xf3]<br>
+@ CHECK: vmvn.i16 d2, #0xa500 @ encoding: [0x35,0x2a,0x82,0xf3]<br>
+@ CHECK: vmvn.i16 q2, #0xa500 @ encoding: [0x75,0x4a,0x82,0xf3]<br>
+@ CHECK: vmvn.i16 d2, #0xa500 @ encoding: [0x35,0x2a,0x82,0xf3]<br>
+@ CHECK: vmvn.i16 q2, #0xa500 @ encoding: [0x75,0x4a,0x82,0xf3]<br>
+<br>
+        vmvn.i64        d2, #0x000000a5000000a5<br>
+        vmvn.i64        q2, #0x000000a5000000a5<br>
+        vmvn.i64        d2, #0x00a5ffff00a5ffff<br>
+        vmvn.i64        q2, #0x00a5ffff00a5ffff<br>
+<br>
+@ CHECK: vmvn.i32 d2, #0xa5 @ encoding: [0x35,0x20,0x82,0xf3]<br>
+@ CHECK: vmvn.i32 q2, #0xa5 @ encoding: [0x75,0x40,0x82,0xf3]<br>
+@ CHECK: vmvn.i32 d2, #0xa5ffff @ encoding: [0x35,0x2d,0x82,0xf3]<br>
+@ CHECK: vmvn.i32 q2, #0xa5ffff @ encoding: [0x75,0x4d,0x82,0xf3]<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>