[llvm] r327704 - [ARM] Fix a check in vmov/vmvn immediate parsing

Mikhail Maltsev via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 16 05:46:49 PDT 2018


Author: miyuki
Date: Fri Mar 16 05:46:49 2018
New Revision: 327704

URL: http://llvm.org/viewvc/llvm-project?rev=327704&view=rev
Log:
[ARM] Fix a check in vmov/vmvn immediate parsing

Summary:
Currently the check is incorrect and the following invalid
instruction is accepted and incorrectly assembled:

  vmov.i32        d2, #0x00a500a6

This patch fixes the issue.

Reviewers: olista01, rengolin

Reviewed By: rengolin

Subscribers: SjoerdMeijer, javed.absar, rogfer01, llvm-commits, kristof.beyls

Differential Revision: https://reviews.llvm.org/D44460

Modified:
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/test/MC/ARM/vmov-vmvn-illegal-cases.s

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=327704&r1=327703&r2=327704&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Fri Mar 16 05:46:49 2018
@@ -1880,6 +1880,17 @@ public:
   bool isNEONi16ByteReplicate() const { return isNEONByteReplicate(2); }
   bool isNEONi32ByteReplicate() const { return isNEONByteReplicate(4); }
 
+  static bool isValidNEONi32vmovImm(int64_t Value) {
+    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
+    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
+    return ((Value & 0xffffffffffffff00) == 0) ||
+           ((Value & 0xffffffffffff00ff) == 0) ||
+           ((Value & 0xffffffffff00ffff) == 0) ||
+           ((Value & 0xffffffff00ffffff) == 0) ||
+           ((Value & 0xffffffffffff00ff) == 0xff) ||
+           ((Value & 0xffffffffff00ffff) == 0xffff);
+  }
+
   bool isNEONi32vmov() const {
     if (isNEONByteReplicate(4))
       return false; // Let it to be classified as byte-replicate case.
@@ -1889,16 +1900,7 @@ public:
     // Must be a constant.
     if (!CE)
       return false;
-    int64_t Value = CE->getValue();
-    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
-    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
-    // FIXME: This is probably wrong and a copy and paste from previous example
-    return (Value >= 0 && Value < 256) ||
-      (Value >= 0x0100 && Value <= 0xff00) ||
-      (Value >= 0x010000 && Value <= 0xff0000) ||
-      (Value >= 0x01000000 && Value <= 0xff000000) ||
-      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
-      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
+    return isValidNEONi32vmovImm(CE->getValue());
   }
 
   bool isNEONi32vmovNeg() const {
@@ -1906,16 +1908,7 @@ public:
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
     // Must be a constant.
     if (!CE) return false;
-    int64_t Value = ~CE->getValue();
-    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
-    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
-    // FIXME: This is probably wrong and a copy and paste from previous example
-    return (Value >= 0 && Value < 256) ||
-      (Value >= 0x0100 && Value <= 0xff00) ||
-      (Value >= 0x010000 && Value <= 0xff0000) ||
-      (Value >= 0x01000000 && Value <= 0xff000000) ||
-      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
-      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
+    return isValidNEONi32vmovImm(~CE->getValue());
   }
 
   bool isNEONi64splat() const {

Modified: llvm/trunk/test/MC/ARM/vmov-vmvn-illegal-cases.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/vmov-vmvn-illegal-cases.s?rev=327704&r1=327703&r2=327704&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/vmov-vmvn-illegal-cases.s (original)
+++ llvm/trunk/test/MC/ARM/vmov-vmvn-illegal-cases.s Fri Mar 16 05:46:49 2018
@@ -10,6 +10,10 @@
 @ CHECK: note: operand must be a register in range [q0, q15]
 @ CHECK: note: invalid operand for instruction
 @ CHECK: error: invalid instruction, any one of the following would fix this:
+@ CHECK-NEXT: vmov.i32        d2, #0x00a500a6
+@ CHECK: note: operand must be a register in range [d0, d31]
+@ CHECK: note: invalid operand for instruction
+@ CHECK: error: invalid instruction, any one of the following would fix this:
 @ CHECK-NEXT: vmov.i16        q2, #0xffab
 @ CHECK: note: operand must be a register in range [q0, q15]
 @ CHECK: note: invalid operand for instruction
@@ -27,6 +31,10 @@
 @ CHECK: note: operand must be a register in range [q0, q15]
 @ CHECK: note: invalid operand for instruction
 @ CHECK: error: invalid instruction, any one of the following would fix this:
+@ CHECK-NEXT: vmvn.i32        d2, #0x00a500a6
+@ CHECK: note: operand must be a register in range [d0, d31]
+@ CHECK: note: invalid operand for instruction
+@ CHECK: error: invalid instruction, any one of the following would fix this:
 @ CHECK-NEXT: vmvn.i16        q2, #0xffab
 @ CHECK: note: operand must be a register in range [q0, q15]
 @ CHECK: note: invalid operand for instruction
@@ -37,10 +45,12 @@
 
         vmov.i32        d2, #0xffffffab
         vmov.i32        q2, #0xffffffab
+        vmov.i32        d2, #0x00a500a6
         vmov.i16        q2, #0xffab
         vmov.i16        q2, #0xffab
 
         vmvn.i32        d2, #0xffffffab
         vmvn.i32        q2, #0xffffffab
+        vmvn.i32        d2, #0x00a500a6
         vmvn.i16        q2, #0xffab
         vmvn.i16        q2, #0xffab




More information about the llvm-commits mailing list