[PATCH] D31948: [AArch64] Fix handling of integer fp immediates

John Brawn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 11 10:16:44 PDT 2017


john.brawn created this revision.
Herald added a subscriber: aemerson.

When an integer is used as an fp immediate we're failing to check the return value of getFP64Imm, so invalid values are silently permitted. Fix this by merging together the integer and real handling.


Repository:
  rL LLVM

https://reviews.llvm.org/D31948

Files:
  lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
  test/MC/AArch64/basic-a64-diagnostics.s


Index: test/MC/AArch64/basic-a64-diagnostics.s
===================================================================
--- test/MC/AArch64/basic-a64-diagnostics.s
+++ test/MC/AArch64/basic-a64-diagnostics.s
@@ -1781,12 +1781,20 @@
         ;; Exponent too large
         fmov d3, #0.0625
         fmov s2, #32.0
+        fmov s2, #32
+        fmov v0.4s, #-32
 // CHECK-ERROR: error: expected compatible register or floating-point constant
 // CHECK-ERROR-NEXT:           fmov d3, #0.0625
 // CHECK-ERROR-NEXT:                    ^
 // CHECK-ERROR-NEXT: error: expected compatible register or floating-point constant
 // CHECK-ERROR-NEXT:           fmov s2, #32.0
 // CHECK-ERROR-NEXT:                    ^
+// CHECK-ERROR-NEXT: error: expected compatible register or floating-point constant
+// CHECK-ERROR-NEXT:           fmov s2, #32
+// CHECK-ERROR-NEXT:                    ^
+// CHECK-ERROR-NEXT: error: expected compatible register or floating-point constant
+// CHECK-ERROR-NEXT:           fmov v0.4s, #-32
+// CHECK-ERROR-NEXT:                       ^
 
         ;; Fraction too precise
         fmov s9, #1.03125
@@ -1798,6 +1806,12 @@
 // CHECK-ERROR-NEXT:           fmov s28, #1.96875
 // CHECK-ERROR-NEXT:                     ^
 
+        ;; Explicitly encoded value too large
+        fmov s15, #0x100
+// CHECK-ERROR: error: encoded floating point value out of range
+// CHECK-ERROR-NEXT:           fmov s15, #0x100
+// CHECK-ERROR-NEXT:                     ^
+
         ;; No particular reason, but a striking omission
         fmov d0, #0.0
 // CHECK-ERROR-AARCH64: error: expected compatible register or floating-point constant
Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
===================================================================
--- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -2100,27 +2100,9 @@
   bool isNegative = parseOptionalToken(AsmToken::Minus);
 
   const AsmToken &Tok = Parser.getTok();
-  if (Tok.is(AsmToken::Real)) {
-    APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
-    if (isNegative)
-      RealVal.changeSign();
-
-    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
-    int Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
-    Parser.Lex(); // Eat the token.
-    // Check for out of range values. As an exception, we let Zero through,
-    // as we handle that special case in post-processing before matching in
-    // order to use the zero register for it.
-    if (Val == -1 && !RealVal.isPosZero()) {
-      TokError("expected compatible register or floating-point constant");
-      return MatchOperand_ParseFail;
-    }
-    Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
-    return MatchOperand_Success;
-  }
-  if (Tok.is(AsmToken::Integer)) {
+  if (Tok.is(AsmToken::Real) || Tok.is(AsmToken::Integer)) {
     int64_t Val;
-    if (!isNegative && Tok.getString().startswith("0x")) {
+    if (Tok.is(AsmToken::Integer) && !isNegative && Tok.getString().startswith("0x")) {
       Val = Tok.getIntVal();
       if (Val > 255 || Val < 0) {
         TokError("encoded floating point value out of range");
@@ -2128,10 +2110,19 @@
       }
     } else {
       APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
+      if (isNegative)
+        RealVal.changeSign();
+
       uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
-      // If we had a '-' in front, toggle the sign bit.
-      IntVal ^= (uint64_t)isNegative << 63;
       Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
+
+      // Check for out of range values. As an exception, we let Zero through,
+      // as we handle that special case in post-processing before matching in
+      // order to use the zero register for it.
+      if (Val == -1 && !RealVal.isPosZero()) {
+        TokError("expected compatible register or floating-point constant");
+        return MatchOperand_ParseFail;
+      }
     }
     Parser.Lex(); // Eat the token.
     Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D31948.94845.patch
Type: text/x-patch
Size: 4077 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170411/b6adeca0/attachment.bin>


More information about the llvm-commits mailing list