[llvm] r355707 - [ARM][FIX] Fix vfmal.f16 and vfmsl.f16 operand

Diogo N. Sampaio via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 8 09:11:20 PST 2019


Author: dnsampaio
Date: Fri Mar  8 09:11:20 2019
New Revision: 355707

URL: http://llvm.org/viewvc/llvm-project?rev=355707&view=rev
Log:
[ARM][FIX] Fix vfmal.f16 and vfmsl.f16 operand

The indexed variant of vfmal.f16 and vfmsl.f16
instructions use the uppser bits of the indexed
operand to store the index (1 bit for the double
variant, 2 bits for the quad).

This limits the usable registers to d0 - d7 or
s0 - s15. This patch enforces this limitation.

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

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
    llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
    llvm/trunk/test/MC/ARM/armv8a-fpmul-error.s

Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=355707&r1=355706&r2=355707&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Fri Mar  8 09:11:20 2019
@@ -5121,10 +5121,11 @@ class N3VCP8F16Q0<string asm, RegisterCl
   : N3VCP8Q0<op1, op2, 0, op3, (outs Td:$Vd), (ins Tn:$Vn, Tm:$Vm), NoItinerary,
            asm, "f16", "$Vd, $Vn, $Vm", "", []>;
 
-class VFMQ0<string opc, bits<2> S>
+// Vd, Vs, Vs[0-15], Idx[0-1]
+class VFMD<string opc, string type, bits<2> S>
   : N3VLaneCP8<0, S, 0, 1, (outs DPR:$Vd),
-               (ins SPR:$Vn, SPR:$Vm, VectorIndex32:$idx),
-               IIC_VMACD, opc, "f16", "$Vd, $Vn, $Vm$idx", "", []> {
+               (ins SPR:$Vn, SPR_8:$Vm, VectorIndex32:$idx),
+               IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> {
   bit idx;
   let Inst{3} = idx;
   let Inst{19-16} = Vn{4-1};
@@ -5133,10 +5134,11 @@ class VFMQ0<string opc, bits<2> S>
   let Inst{2-0}   = Vm{3-1};
 }
 
-class VFMQ1<string opc, bits<2> S>
+// Vq, Vd, Vd[0-7], Idx[0-3]
+class VFMQ<string opc, string type, bits<2> S>
   : N3VLaneCP8<0, S, 1, 1, (outs QPR:$Vd),
-               (ins DPR:$Vn, DPR:$Vm, VectorIndex16:$idx),
-               IIC_VMACD, opc, "f16", "$Vd, $Vn, $Vm$idx", "", []> {
+               (ins DPR:$Vn, DPR_8:$Vm, VectorIndex16:$idx),
+               IIC_VMACD, opc, type, "$Vd, $Vn, $Vm$idx", "", []> {
   bits<2> idx;
   let Inst{5} = idx{1};
   let Inst{3} = idx{0};
@@ -5148,10 +5150,10 @@ def VFMALD  : N3VCP8F16Q0<"vfmal", DPR,
 def VFMSLD  : N3VCP8F16Q0<"vfmsl", DPR, SPR, SPR, 0b01, 0b10, 1>;
 def VFMALQ  : N3VCP8F16Q1<"vfmal", QPR, DPR, DPR, 0b00, 0b10, 1>;
 def VFMSLQ  : N3VCP8F16Q1<"vfmsl", QPR, DPR, DPR, 0b01, 0b10, 1>;
-def VFMALDI : VFMQ0<"vfmal", 0b00>;
-def VFMSLDI : VFMQ0<"vfmsl", 0b01>;
-def VFMALQI : VFMQ1<"vfmal", 0b00>;
-def VFMSLQI : VFMQ1<"vfmsl", 0b01>;
+def VFMALDI : VFMD<"vfmal", "f16", 0b00>;
+def VFMSLDI : VFMD<"vfmsl", "f16", 0b01>;
+def VFMALQI : VFMQ<"vfmal", "f16", 0b00>;
+def VFMSLQI : VFMQ<"vfmsl", "f16", 0b01>;
 }
 } // HasNEON, HasFP16FML
 

Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=355707&r1=355706&r2=355707&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Fri Mar  8 09:11:20 2019
@@ -165,6 +165,8 @@ static DecodeStatus DecodeDPRRegisterCla
                                    uint64_t Address, const void *Decoder);
 static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
                                    uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
+                                   uint64_t Address, const void *Decoder);
 static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
                                                 unsigned RegNo,
                                                 uint64_t Address,
@@ -1045,6 +1047,13 @@ static DecodeStatus DecodeDPR_8RegisterC
   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
 }
 
+static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
+                                   uint64_t Address, const void *Decoder) {
+  if (RegNo > 15)
+    return MCDisassembler::Fail;
+  return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
+}
+
 static DecodeStatus
 DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
                             uint64_t Address, const void *Decoder) {

Modified: llvm/trunk/test/MC/ARM/armv8a-fpmul-error.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/armv8a-fpmul-error.s?rev=355707&r1=355706&r2=355707&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/armv8a-fpmul-error.s (original)
+++ llvm/trunk/test/MC/ARM/armv8a-fpmul-error.s Fri Mar  8 09:11:20 2019
@@ -6,6 +6,10 @@ vfmsl.f16 d0, s1, s2[-1]
 vfmal.f16 q0, d1, d2[4]
 VFMSL.F16 Q0, D1, D2[4]
 vfmal.f16 q0, d1, d2[-1]
+VFMSL.F16 D0, S1, S16[0]
+vfmal.f16 d0, s1, s16[0]
+VFMSL.F16 Q0, D1, D8[0]
+vfmal.f16 q0, d1, d8[0]
 
 //CHECK-ERROR:      error: invalid operand for instruction
 //CHECK-ERROR-NEXT: VFMAL.F16 D0, S1, S2[2]
@@ -25,3 +29,39 @@ vfmal.f16 q0, d1, d2[-1]
 //CHECK-ERROR-NEXT: error: invalid operand for instruction
 //CHECK-ERROR-NEXT: vfmal.f16 q0, d1, d2[-1]
 //CHECK-ERROR-NEXT:                     ^
+//CHECK-ERROR-NEXT: error: invalid instruction, any one of the following would fix this:
+//CHECK-ERROR-NEXT: VFMSL.F16 D0, S1, S16[0]
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: note: operand must be a register in range [s0, s15]
+//CHECK-ERROR-NEXT: VFMSL.F16 D0, S1, S16[0]
+//CHECK-ERROR-NEXT:                   ^
+//CHECK-ERROR-NEXT: note: too many operands for instruction
+//CHECK-ERROR-NEXT: VFMSL.F16 D0, S1, S16[0]
+//CHECK-ERROR-NEXT:                      ^
+//CHECK-ERROR-NEXT: error: invalid instruction, any one of the following would fix this:
+//CHECK-ERROR-NEXT: vfmal.f16 d0, s1, s16[0]
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: note: operand must be a register in range [s0, s15]
+//CHECK-ERROR-NEXT: vfmal.f16 d0, s1, s16[0]
+//CHECK-ERROR-NEXT:                   ^
+//CHECK-ERROR-NEXT: note: too many operands for instruction
+//CHECK-ERROR-NEXT: vfmal.f16 d0, s1, s16[0]
+//CHECK-ERROR-NEXT:                      ^
+//CHECK-ERROR-NEXT: : error: invalid instruction, any one of the following would fix this:
+//CHECK-ERROR-NEXT: VFMSL.F16 Q0, D1, D8[0]
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: : note: operand must be a register in range [d0, d7]
+//CHECK-ERROR-NEXT: VFMSL.F16 Q0, D1, D8[0]
+//CHECK-ERROR-NEXT:                   ^
+//CHECK-ERROR-NEXT: : note: too many operands for instruction
+//CHECK-ERROR-NEXT: VFMSL.F16 Q0, D1, D8[0]
+//CHECK-ERROR-NEXT:                     ^
+//CHECK-ERROR-NEXT: : error: invalid instruction, any one of the following would fix this:
+//CHECK-ERROR-NEXT: vfmal.f16 q0, d1, d8[0]
+//CHECK-ERROR-NEXT: ^
+//CHECK-ERROR-NEXT: : note: operand must be a register in range [d0, d7]
+//CHECK-ERROR-NEXT: vfmal.f16 q0, d1, d8[0]
+//CHECK-ERROR-NEXT:                   ^
+//CHECK-ERROR-NEXT: 1: note: too many operands for instruction
+//CHECK-ERROR-NEXT: vfmal.f16 q0, d1, d8[0]
+//CHECK-ERROR-NEXT:                     ^




More information about the llvm-commits mailing list