<div dir="ltr">MSan bootstrap reports an error: <a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/10100/steps/check-llvm%20msan/logs/stdio" target="_blank">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/10100/steps/check-llvm%20msan/logs/stdio</a><div>Please investigate.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 10, 2016 at 7:28 PM, Tom Stellard 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: tstellar<br>
Date: Wed Feb 10 21:28:15 2016<br>
New Revision: 260483<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=260483&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=260483&view=rev</a><br>
Log:<br>
[AMDGPU] Assembler: Fix VOP3 only instructions<br>
<br>
Separate methods to convert parsed instructions to MCInst:<br>
<br>
  - VOP3 only instructions (always create modifiers as operands in MCInst)<br>
  - VOP2 instrunctions with modifiers (create modifiers as operands<br>
    in MCInst when e64 encoding is forced or modifiers are parsed)<br>
  - VOP2 instructions without modifiers (do not create modifiers<br>
    as operands in MCInst)<br>
  - Add VOP3Only flag. Pass HasMods flag to VOP3Common.<br>
  - Simplify code that deals with modifiers (-1 is now same as<br>
    0). This is no longer needed.<br>
  - Add few tests (more will be added separately).<br>
    Update error message now correct.<br>
<br>
Patch By: Nikolay Haustov<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D16778" rel="noreferrer" target="_blank">http://reviews.llvm.org/D16778</a><br>
<br>
Modified:<br>
    llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp<br>
    llvm/trunk/lib/Target/AMDGPU/SIInstrFormats.td<br>
    llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td<br>
    llvm/trunk/lib/Target/AMDGPU/SIInstructions.td<br>
    llvm/trunk/test/MC/AMDGPU/vop3.s<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp?rev=260483&r1=260482&r2=260483&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp?rev=260483&r1=260482&r2=260483&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp Wed Feb 10 21:28:15 2016<br>
@@ -116,8 +116,7 @@ public:<br>
   }<br>
<br>
   void addRegWithInputModsOperands(MCInst &Inst, unsigned N) const {<br>
-    Inst.addOperand(MCOperand::createImm(<br>
-        Reg.Modifiers == -1 ? 0 : Reg.Modifiers));<br>
+    Inst.addOperand(MCOperand::createImm(Reg.Modifiers));<br>
     addRegOperands(Inst, N);<br>
   }<br>
<br>
@@ -176,11 +175,23 @@ public:<br>
   }<br>
<br>
   bool isReg() const override {<br>
-    return Kind == Register && Reg.Modifiers == -1;<br>
+    return Kind == Register && Reg.Modifiers == 0;<br>
   }<br>
<br>
   bool isRegWithInputMods() const {<br>
-    return Kind == Register && (Reg.IsForcedVOP3 || Reg.Modifiers != -1);<br>
+    return Kind == Register;<br>
+  }<br>
+<br>
+  bool isClamp() const {<br>
+    return isImm() && Imm.Type == ImmTyClamp;<br>
+  }<br>
+<br>
+  bool isOMod() const {<br>
+    return isImm() && Imm.Type == ImmTyOMod;<br>
+  }<br>
+<br>
+  bool isMod() const {<br>
+    return isClamp() || isOMod();<br>
   }<br>
<br>
   void setModifiers(unsigned Mods) {<br>
@@ -190,7 +201,7 @@ public:<br>
<br>
   bool hasModifiers() const {<br>
     assert(isRegKind());<br>
-    return Reg.Modifiers != -1;<br>
+    return Reg.Modifiers != 0;<br>
   }<br>
<br>
   unsigned getReg() const override {<br>
@@ -202,7 +213,7 @@ public:<br>
   }<br>
<br>
   bool isRegClass(unsigned RCID) const {<br>
-    return Reg.TRI->getRegClass(RCID).contains(getReg());<br>
+    return isReg() && Reg.TRI->getRegClass(RCID).contains(getReg());<br>
   }<br>
<br>
   bool isSCSrc32() const {<br>
@@ -306,7 +317,7 @@ public:<br>
     Op->Reg.RegNo = RegNo;<br>
     Op->Reg.TRI = TRI;<br>
     Op->Reg.STI = STI;<br>
-    Op->Reg.Modifiers = -1;<br>
+    Op->Reg.Modifiers = 0;<br>
     Op->Reg.IsForcedVOP3 = ForceVOP3;<br>
     Op->StartLoc = S;<br>
     Op->EndLoc = E;<br>
@@ -462,6 +473,10 @@ public:<br>
   OperandMatchResultTy parseUNorm(OperandVector &Operands);<br>
   OperandMatchResultTy parseR128(OperandVector &Operands);<br>
<br>
+  void cvtId(MCInst &Inst, const OperandVector &Operands);<br>
+  void cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands);<br>
+  void cvtVOP3_2_nomod(MCInst &Inst, const OperandVector &Operands);<br>
+  void cvtVOP3_only(MCInst &Inst, const OperandVector &Operands);<br>
   void cvtVOP3(MCInst &Inst, const OperandVector &Operands);<br>
   OperandMatchResultTy parseVOP3OptionalOps(OperandVector &Operands);<br>
 };<br>
@@ -1103,7 +1118,7 @@ AMDGPUAsmParser::parseOperand(OperandVec<br>
   // If we are parsing after we reach EndOfStatement then this means we<br>
   // are appending default values to the Operands list.  This is only done<br>
   // by custom parser, so we shouldn't continue on to the generic parsing.<br>
-  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail ||<br>
+  if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail||<br>
       getLexer().is(AsmToken::EndOfStatement))<br>
     return ResTy;<br>
<br>
@@ -1153,8 +1168,6 @@ AMDGPUAsmParser::parseOperand(OperandVec<br>
       SMLoc S, E;<br>
       unsigned RegNo;<br>
       if (!ParseRegister(RegNo, S, E)) {<br>
-<br>
-        bool HasModifiers = operandsHaveModifiers(Operands);<br>
         unsigned Modifiers = 0;<br>
<br>
         if (Negate)<br>
@@ -1167,34 +1180,23 @@ AMDGPUAsmParser::parseOperand(OperandVec<br>
           Modifiers |= 0x2;<br>
         }<br>
<br>
-        if (Modifiers && !HasModifiers) {<br>
-          // We are adding a modifier to src1 or src2 and previous sources<br>
-          // don't have modifiers, so we need to go back and empty modifers<br>
-          // for each previous source.<br>
-          for (unsigned PrevRegIdx = Operands.size() - 1; PrevRegIdx > 1;<br>
-               --PrevRegIdx) {<br>
-<br>
-            AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[PrevRegIdx]);<br>
-            RegOp.setModifiers(0);<br>
-          }<br>
-        }<br>
-<br>
-<br>
         Operands.push_back(AMDGPUOperand::CreateReg(<br>
             RegNo, S, E, getContext().getRegisterInfo(), &getSTI(),<br>
             isForcedVOP3()));<br>
<br>
-        if (HasModifiers || Modifiers) {<br>
+        if (Modifiers) {<br>
           AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[Operands.size() - 1]);<br>
           RegOp.setModifiers(Modifiers);<br>
-<br>
         }<br>
-     }  else {<br>
-      Operands.push_back(AMDGPUOperand::CreateToken(Parser.getTok().getString(),<br>
-                                                    S));<br>
-      Parser.Lex();<br>
-     }<br>
-     return MatchOperand_Success;<br>
+      } else {<br>
+        ResTy = parseVOP3OptionalOps(Operands);<br>
+        if (ResTy == MatchOperand_NoMatch) {<br>
+          Operands.push_back(AMDGPUOperand::CreateToken(Parser.getTok().getString(),<br>
+                                                        S));<br>
+          Parser.Lex();<br>
+        }<br>
+      }<br>
+      return MatchOperand_Success;<br>
     }<br>
     default:<br>
       return MatchOperand_NoMatch;<br>
@@ -1802,10 +1804,12 @@ static bool isVOP3(OperandVector &Operan<br>
   if (operandsHaveModifiers(Operands))<br>
     return true;<br>
<br>
-  AMDGPUOperand &DstOp = ((AMDGPUOperand&)*Operands[1]);<br>
+  if (Operands.size() >= 2) {<br>
+    AMDGPUOperand &DstOp = ((AMDGPUOperand&)*Operands[1]);<br>
<br>
-  if (DstOp.isReg() && DstOp.isRegClass(AMDGPU::SGPR_64RegClassID))<br>
-    return true;<br>
+    if (DstOp.isReg() && DstOp.isRegClass(AMDGPU::SGPR_64RegClassID))<br>
+      return true;<br>
+  }<br>
<br>
   if (Operands.size() >= 5)<br>
     return true;<br>
@@ -1848,35 +1852,70 @@ AMDGPUAsmParser::parseVOP3OptionalOps(Op<br>
   return MatchOperand_NoMatch;<br>
 }<br>
<br>
-void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {<br>
-<br>
-  unsigned i = 1;<br>
+void AMDGPUAsmParser::cvtId(MCInst &Inst, const OperandVector &Operands) {<br>
+  unsigned I = 1;<br>
   const MCInstrDesc &Desc = MII.get(Inst.getOpcode());<br>
   if (Desc.getNumDefs() > 0) {<br>
-    ((AMDGPUOperand &)*Operands[i++]).addRegOperands(Inst, 1);<br>
+    ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);<br>
   }<br>
+  for (unsigned E = Operands.size(); I != E; ++I)<br>
+    ((AMDGPUOperand &)*Operands[I]).addRegOrImmOperands(Inst, 1);<br>
+}<br>
<br>
-  std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;<br>
+void AMDGPUAsmParser::cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands) {<br>
+  if (operandsHaveModifiers(Operands) || isForcedVOP3()) {<br>
+    cvtVOP3(Inst, Operands);<br>
+  } else {<br>
+    cvtId(Inst, Operands);<br>
+  }<br>
+}<br>
<br>
+void AMDGPUAsmParser::cvtVOP3_2_nomod(MCInst &Inst, const OperandVector &Operands) {<br>
   if (operandsHaveModifiers(Operands)) {<br>
-    for (unsigned e = Operands.size(); i != e; ++i) {<br>
-      AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);<br>
+    cvtVOP3(Inst, Operands);<br>
+  } else {<br>
+    cvtId(Inst, Operands);<br>
+  }<br>
+}<br>
<br>
-      if (Op.isRegWithInputMods()) {<br>
-        ((AMDGPUOperand &)*Operands[i]).addRegWithInputModsOperands(Inst, 2);<br>
-        continue;<br>
-      }<br>
-      OptionalIdx[Op.getImmTy()] = i;<br>
-    }<br>
+void AMDGPUAsmParser::cvtVOP3_only(MCInst &Inst, const OperandVector &Operands) {<br>
+  cvtVOP3(Inst, Operands);<br>
+}<br>
<br>
-    unsigned ClampIdx = OptionalIdx[AMDGPUOperand::ImmTyClamp];<br>
-    unsigned OModIdx = OptionalIdx[AMDGPUOperand::ImmTyOMod];<br>
+void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {<br>
+  unsigned I = 1;<br>
+  const MCInstrDesc &Desc = MII.get(Inst.getOpcode());<br>
+  if (Desc.getNumDefs() > 0) {<br>
+    ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);<br>
+  }<br>
<br>
-    ((AMDGPUOperand &)*Operands[ClampIdx]).addImmOperands(Inst, 1);<br>
-    ((AMDGPUOperand &)*Operands[OModIdx]).addImmOperands(Inst, 1);<br>
+  unsigned ClampIdx = 0, OModIdx = 0;<br>
+  for (unsigned E = Operands.size(); I != E; ++I) {<br>
+    AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);<br>
+    if (Op.isRegWithInputMods()) {<br>
+      Op.addRegWithInputModsOperands(Inst, 2);<br>
+    } else if (Op.isClamp()) {<br>
+      ClampIdx = I;<br>
+    } else if (Op.isOMod()) {<br>
+      OModIdx = I;<br>
+    } else if (Op.isImm()) {<br>
+      Op.addImmOperands(Inst, 1);<br>
+    } else {<br>
+      assert(false);<br>
+    }<br>
+  }<br>
+<br>
+  if (ClampIdx) {<br>
+    AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[ClampIdx]);<br>
+    Op.addImmOperands(Inst, 1);<br>
+  } else {<br>
+    Inst.addOperand(MCOperand::createImm(0));<br>
+  }<br>
+  if (OModIdx) {<br>
+    AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[OModIdx]);<br>
+    Op.addImmOperands(Inst, 1);<br>
   } else {<br>
-    for (unsigned e = Operands.size(); i != e; ++i)<br>
-      ((AMDGPUOperand &)*Operands[i]).addRegOrImmOperands(Inst, 1);<br>
+    Inst.addOperand(MCOperand::createImm(0));<br>
   }<br>
 }<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/SIInstrFormats.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIInstrFormats.td?rev=260483&r1=260482&r2=260483&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIInstrFormats.td?rev=260483&r1=260482&r2=260483&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AMDGPU/SIInstrFormats.td (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/SIInstrFormats.td Wed Feb 10 21:28:15 2016<br>
@@ -123,7 +123,7 @@ class VOP2Common <dag outs, dag ins, str<br>
   let Size = 4;<br>
 }<br>
<br>
-class VOP3Common <dag outs, dag ins, string asm, list<dag> pattern> :<br>
+class VOP3Common <dag outs, dag ins, string asm, list<dag> pattern, bit HasMods = 0, bit VOP3Only = 0> :<br>
     VOPAnyCommon <outs, ins, asm, pattern> {<br>
<br>
   // Using complex patterns gives VOP3 patterns a very high complexity rating,<br>
@@ -135,7 +135,10 @@ class VOP3Common <dag outs, dag ins, str<br>
   let VOP3 = 1;<br>
   let VALU = 1;<br>
<br>
-  let AsmMatchConverter = "cvtVOP3";<br>
+  let AsmMatchConverter =<br>
+    !if(!eq(VOP3Only,1),<br>
+        "cvtVOP3_only",<br>
+        !if(!eq(HasMods,1), "cvtVOP3_2_mod", "cvtVOP3_2_nomod"));<br>
   let isCodeGenOnly = 0;<br>
<br>
   int Size = 8;<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td?rev=260483&r1=260482&r2=260483&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td?rev=260483&r1=260482&r2=260483&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/SIInstrInfo.td Wed Feb 10 21:28:15 2016<br>
@@ -477,6 +477,7 @@ def OModMatchClass : AsmOperandClass {<br>
   let PredicateMethod = "isImm";<br>
   let ParserMethod = "parseVOP3OptionalOps";<br>
   let RenderMethod = "addImmOperands";<br>
+  let IsOptional = 1;<br>
 }<br>
<br>
 def ClampMatchClass : AsmOperandClass {<br>
@@ -484,6 +485,7 @@ def ClampMatchClass : AsmOperandClass {<br>
   let PredicateMethod = "isImm";<br>
   let ParserMethod = "parseVOP3OptionalOps";<br>
   let RenderMethod = "addImmOperands";<br>
+  let IsOptional = 1;<br>
 }<br>
<br>
 class SMRDOffsetBaseMatchClass <string predicate> : AsmOperandClass {<br>
@@ -1072,8 +1074,10 @@ class getVOP3SrcForVT<ValueType VT> {<br>
 // Returns 1 if the source arguments have modifiers, 0 if they do not.<br>
 // XXX - do f16 instructions?<br>
 class hasModifiers<ValueType SrcVT> {<br>
-  bit ret = !if(!eq(SrcVT.Value, f32.Value), 1,<br>
-            !if(!eq(SrcVT.Value, f64.Value), 1, 0));<br>
+  bit ret =<br>
+    !if(!eq(SrcVT.Value, f32.Value), 1,<br>
+    !if(!eq(SrcVT.Value, f64.Value), 1,<br>
+    0));<br>
 }<br>
<br>
 // Returns the input arguments for VOP[12C] instructions for the given SrcVT.<br>
@@ -1471,8 +1475,9 @@ class VOP3DisableModFields <bit HasSrc0M<br>
   bits<1> clamp = !if(HasOutputMods, ?, 0);<br>
 }<br>
<br>
-class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :<br>
-  VOP3Common <outs, ins, "", pattern>,<br>
+class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName,<br>
+                   bit HasMods = 0, bit VOP3Only = 0> :<br>
+  VOP3Common <outs, ins, "", pattern, HasMods, VOP3Only>,<br>
   VOP <opName>,<br>
   SIMCInstr<opName#"_e64", SISubtarget.NONE>,<br>
   MnemonicAlias<opName#"_e64", opName> {<br>
@@ -1483,44 +1488,48 @@ class VOP3_Pseudo <dag outs, dag ins, li<br>
   field bit src0;<br>
 }<br>
<br>
-class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :<br>
-  VOP3Common <outs, ins, asm, []>,<br>
+class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,<br>
+                    bit HasMods = 0, bit VOP3Only = 0> :<br>
+  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,<br>
   VOP3e <op>,<br>
   SIMCInstr<opName#"_e64", SISubtarget.SI> {<br>
   let AssemblerPredicates = [isSICI];<br>
 }<br>
<br>
-class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :<br>
-  VOP3Common <outs, ins, asm, []>,<br>
+class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,<br>
+                    bit HasMods = 0, bit VOP3Only = 0> :<br>
+  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,<br>
   VOP3e_vi <op>,<br>
   SIMCInstr <opName#"_e64", SISubtarget.VI> {<br>
   let AssemblerPredicates = [isVI];<br>
 }<br>
<br>
-class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :<br>
-  VOP3Common <outs, ins, asm, []>,<br>
+class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,<br>
+                     bit HasMods = 0, bit VOP3Only = 0> :<br>
+  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,<br>
   VOP3be <op>,<br>
   SIMCInstr<opName#"_e64", SISubtarget.SI> {<br>
   let AssemblerPredicates = [isSICI];<br>
 }<br>
<br>
-class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :<br>
-  VOP3Common <outs, ins, asm, []>,<br>
+class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,<br>
+                     bit HasMods = 0, bit VOP3Only = 0> :<br>
+  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,<br>
   VOP3be_vi <op>,<br>
   SIMCInstr <opName#"_e64", SISubtarget.VI> {<br>
   let AssemblerPredicates = [isVI];<br>
 }<br>
<br>
 multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern,<br>
-                   string opName, int NumSrcArgs, bit HasMods = 1> {<br>
+                   string opName, int NumSrcArgs, bit HasMods = 1, bit VOP3Only = 0> {<br>
<br>
   def "" : VOP3_Pseudo <outs, ins, pattern, opName>;<br>
<br>
-  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,<br>
+  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>,<br>
             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),<br>
                               !if(!eq(NumSrcArgs, 2), 0, 1),<br>
                               HasMods>;<br>
-  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,<br>
+  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>,<br>
             VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),<br>
                               !if(!eq(NumSrcArgs, 2), 0, 1),<br>
                               HasMods>;<br>
@@ -1529,21 +1538,21 @@ multiclass VOP3_m <vop op, dag outs, dag<br>
 multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,<br>
                      list<dag> pattern, string opName, bit HasMods = 1> {<br>
<br>
-  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;<br>
+  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>;<br>
<br>
-  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,<br>
+  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,<br>
             VOP3DisableFields<0, 0, HasMods>;<br>
<br>
-  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,<br>
+  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,<br>
             VOP3DisableFields<0, 0, HasMods>;<br>
 }<br>
<br>
 multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm,<br>
                      list<dag> pattern, string opName, bit HasMods = 1> {<br>
<br>
-  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;<br>
+  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>;<br>
<br>
-  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,<br>
+  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,<br>
             VOP3DisableFields<0, 0, HasMods>;<br>
   // No VI instruction. This class is for SI only.<br>
 }<br>
@@ -1552,13 +1561,13 @@ multiclass VOP3_2_m <vop op, dag outs, d<br>
                      list<dag> pattern, string opName, string revOp,<br>
                      bit HasMods = 1> {<br>
<br>
-  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,<br>
+  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,<br>
            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;<br>
<br>
-  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,<br>
+  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,<br>
             VOP3DisableFields<1, 0, HasMods>;<br>
<br>
-  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,<br>
+  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,<br>
             VOP3DisableFields<1, 0, HasMods>;<br>
 }<br>
<br>
@@ -1566,10 +1575,10 @@ multiclass VOP3SI_2_m <vop op, dag outs,<br>
                      list<dag> pattern, string opName, string revOp,<br>
                      bit HasMods = 1> {<br>
<br>
-  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,<br>
+  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,<br>
            VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;<br>
<br>
-  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,<br>
+  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,<br>
             VOP3DisableFields<1, 0, HasMods>;<br>
<br>
   // No VI instruction. This class is for SI only.<br>
@@ -1594,19 +1603,19 @@ multiclass VOP3_C_m <vop op, dag outs, d<br>
                      bit HasMods, bit defExec,<br>
                      string revOp, list<SchedReadWrite> sched> {<br>
<br>
-  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,<br>
+  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,<br>
            VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {<br>
     let Defs = !if(defExec, [EXEC], []);<br>
     let SchedRW = sched;<br>
   }<br>
<br>
-  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,<br>
+  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,<br>
             VOP3DisableFields<1, 0, HasMods> {<br>
     let Defs = !if(defExec, [EXEC], []);<br>
     let SchedRW = sched;<br>
   }<br>
<br>
-  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,<br>
+  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,<br>
             VOP3DisableFields<1, 0, HasMods> {<br>
     let Defs = !if(defExec, [EXEC], []);<br>
     let SchedRW = sched;<br>
@@ -1900,8 +1909,9 @@ multiclass VOPCX_I64 <vopc op, string op<br>
   VOPCX <op, opName, VOPC_I1_I64_I64, COND_NULL, [Write64Bit], revOp>;<br>
<br>
 multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,<br>
-                        list<dag> pat, int NumSrcArgs, bit HasMods> : VOP3_m <<br>
-    op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods<br>
+                        list<dag> pat, int NumSrcArgs, bit HasMods,<br>
+                        bit VOP3Only = 0> : VOP3_m <<br>
+    op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods, VOP3Only<br>
 >;<br>
<br>
 multiclass VOPC_CLASS_F32 <vopc op, string opName> :<br>
@@ -1917,7 +1927,8 @@ multiclass VOPCX_CLASS_F64 <vopc op, str<br>
   VOPCClassInst <op, opName, VOPC_I1_F64_I32, 1, [WriteDoubleAdd]>;<br>
<br>
 multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,<br>
-                     SDPatternOperator node = null_frag> : VOP3_Helper <<br>
+                     SDPatternOperator node = null_frag, bit VOP3Only = 0> :<br>
+  VOP3_Helper <<br>
   op, opName, (outs P.DstRC.RegClass:$dst), P.Ins64, P.Asm64,<br>
   !if(!eq(P.NumSrcArgs, 3),<br>
     !if(P.HasModifiers,<br>
@@ -1941,7 +1952,7 @@ multiclass VOP3Inst <vop3 op, string opN<br>
             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,<br>
                                        i1:$clamp, i32:$omod))))],<br>
         [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))),<br>
-  P.NumSrcArgs, P.HasModifiers<br>
+  P.NumSrcArgs, P.HasModifiers, VOP3Only<br>
 >;<br>
<br>
 // Special case for v_div_fmas_{f32|f64}, since it seems to be the<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/SIInstructions.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIInstructions.td?rev=260483&r1=260482&r2=260483&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/SIInstructions.td?rev=260483&r1=260482&r2=260483&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AMDGPU/SIInstructions.td (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/SIInstructions.td Wed Feb 10 21:28:15 2016<br>
@@ -1727,23 +1727,23 @@ let SchedRW = [WriteDoubleAdd] in {<br>
 let isCommutable = 1 in {<br>
<br>
 defm V_ADD_F64 : VOP3Inst <vop3<0x164, 0x280>, "v_add_f64",<br>
-  VOP_F64_F64_F64, fadd<br>
+  VOP_F64_F64_F64, fadd, 1<br>
 >;<br>
 defm V_MUL_F64 : VOP3Inst <vop3<0x165, 0x281>, "v_mul_f64",<br>
-  VOP_F64_F64_F64, fmul<br>
+  VOP_F64_F64_F64, fmul, 1<br>
 >;<br>
<br>
 defm V_MIN_F64 : VOP3Inst <vop3<0x166, 0x282>, "v_min_f64",<br>
-  VOP_F64_F64_F64, fminnum<br>
+  VOP_F64_F64_F64, fminnum, 1<br>
 >;<br>
 defm V_MAX_F64 : VOP3Inst <vop3<0x167, 0x283>, "v_max_f64",<br>
-  VOP_F64_F64_F64, fmaxnum<br>
+  VOP_F64_F64_F64, fmaxnum, 1<br>
 >;<br>
<br>
 } // End isCommutable = 1<br>
<br>
 defm V_LDEXP_F64 : VOP3Inst <vop3<0x168, 0x284>, "v_ldexp_f64",<br>
-  VOP_F64_F64_I32, AMDGPUldexp<br>
+  VOP_F64_F64_I32, AMDGPUldexp, 1<br>
 >;<br>
<br>
 } // End let SchedRW = [WriteDoubleAdd]<br>
<br>
Modified: llvm/trunk/test/MC/AMDGPU/vop3.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/vop3.s?rev=260483&r1=260482&r2=260483&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/vop3.s?rev=260483&r1=260482&r2=260483&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/AMDGPU/vop3.s (original)<br>
+++ llvm/trunk/test/MC/AMDGPU/vop3.s Wed Feb 10 21:28:15 2016<br>
@@ -198,8 +198,7 @@ v_subrev_f32 v1, v3, s5<br>
<br>
 v_mac_legacy_f32 v1, v3, s5<br>
 // SICI: v_mac_legacy_f32_e64 v1, v3, s5 ; encoding: [0x01,0x00,0x0c,0xd2,0x03,0x0b,0x00,0x00]<br>
-// FIXME: The error message should be: error: instruction not supported on this GPU<br>
-// NOVI: error: invalid operand for instruction<br>
+// NOVI: error: instruction not supported on this GPU<br>
<br>
 v_mul_legacy_f32 v1, v3, s5<br>
 // SICI: v_mul_legacy_f32_e64 v1, v3, s5 ; encoding: [0x01,0x00,0x0e,0xd2,0x03,0x0b,0x00,0x00]<br>
@@ -223,7 +222,51 @@ v_mad_legacy_f32 v2, v4, v6, v8<br>
 // SICI: v_mad_legacy_f32 v2, v4, v6, v8 ; encoding: [0x02,0x00,0x80,0xd2,0x04,0x0d,0x22,0x04]<br>
 // VI:   v_mad_legacy_f32 v2, v4, v6, v8 ; encoding: [0x02,0x00,0xc0,0xd1,0x04,0x0d,0x22,0x04]<br>
<br>
-<br>
-<br>
-<br>
+v_add_f64 v[0:1], v[2:3], v[5:6]<br>
+// SICI: v_add_f64 v[0:1], v[2:3], v[5:6] ; encoding: [0x00,0x00,0xc8,0xd2,0x02,0x0b,0x02,0x00]<br>
+// VI:   v_add_f64 v[0:1], v[2:3], v[5:6] ; encoding: [0x00,0x00,0x80,0xd2,0x02,0x0b,0x02,0x00]<br>
+<br>
+v_add_f64_e64 v[0:1], v[2:3], v[5:6]<br>
+// SICI: v_add_f64 v[0:1], v[2:3], v[5:6] ; encoding: [0x00,0x00,0xc8,0xd2,0x02,0x0b,0x02,0x00]<br>
+// VI:   v_add_f64 v[0:1], v[2:3], v[5:6] ; encoding: [0x00,0x00,0x80,0xd2,0x02,0x0b,0x02,0x00]<br>
+<br>
+v_add_f64 v[0:1], -v[2:3], v[5:6]<br>
+// SICI: v_add_f64 v[0:1], -v[2:3], v[5:6] ; encoding: [0x00,0x00,0xc8,0xd2,0x02,0x0b,0x02,0x20]<br>
+// VI:   v_add_f64 v[0:1], -v[2:3], v[5:6] ; encoding: [0x00,0x00,0x80,0xd2,0x02,0x0b,0x02,0x20]<br>
+<br>
+v_add_f64_e64 v[0:1], -v[2:3], v[5:6]<br>
+// SICI: v_add_f64 v[0:1], -v[2:3], v[5:6] ; encoding: [0x00,0x00,0xc8,0xd2,0x02,0x0b,0x02,0x20]<br>
+// VI:   v_add_f64 v[0:1], -v[2:3], v[5:6] ; encoding: [0x00,0x00,0x80,0xd2,0x02,0x0b,0x02,0x20]<br>
+<br>
+v_add_f64 v[0:1], v[2:3], -v[5:6]<br>
+// SICI: v_add_f64 v[0:1], v[2:3], -v[5:6] ; encoding: [0x00,0x00,0xc8,0xd2,0x02,0x0b,0x02,0x40]<br>
+// VI:   v_add_f64 v[0:1], v[2:3], -v[5:6] ; encoding: [0x00,0x00,0x80,0xd2,0x02,0x0b,0x02,0x40]<br>
+<br>
+v_add_f64_e64 v[0:1], v[2:3], -v[5:6]<br>
+// SICI: v_add_f64 v[0:1], v[2:3], -v[5:6] ; encoding: [0x00,0x00,0xc8,0xd2,0x02,0x0b,0x02,0x40]<br>
+// VI:   v_add_f64 v[0:1], v[2:3], -v[5:6] ; encoding: [0x00,0x00,0x80,0xd2,0x02,0x0b,0x02,0x40]<br>
+<br>
+v_add_f64 v[0:1], |v[2:3]|, v[5:6]<br>
+// SICI: v_add_f64 v[0:1], |v[2:3]|, v[5:6] ; encoding: [0x00,0x01,0xc8,0xd2,0x02,0x0b,0x02,0x00]<br>
+// VI:   v_add_f64 v[0:1], |v[2:3]|, v[5:6] ; encoding: [0x00,0x01,0x80,0xd2,0x02,0x0b,0x02,0x00]<br>
+<br>
+v_add_f64_e64 v[0:1], |v[2:3]|, v[5:6]<br>
+// SICI: v_add_f64 v[0:1], |v[2:3]|, v[5:6] ; encoding: [0x00,0x01,0xc8,0xd2,0x02,0x0b,0x02,0x00]<br>
+// VI:   v_add_f64 v[0:1], |v[2:3]|, v[5:6] ; encoding: [0x00,0x01,0x80,0xd2,0x02,0x0b,0x02,0x00]<br>
+<br>
+v_add_f64 v[0:1], v[2:3], |v[5:6]|<br>
+// SICI: v_add_f64 v[0:1], v[2:3], |v[5:6]| ; encoding: [0x00,0x02,0xc8,0xd2,0x02,0x0b,0x02,0x00]<br>
+// VI:   v_add_f64 v[0:1], v[2:3], |v[5:6]| ; encoding: [0x00,0x02,0x80,0xd2,0x02,0x0b,0x02,0x00]<br>
+<br>
+v_add_f64_e64 v[0:1], v[2:3], |v[5:6]|<br>
+// SICI: v_add_f64 v[0:1], v[2:3], |v[5:6]| ; encoding: [0x00,0x02,0xc8,0xd2,0x02,0x0b,0x02,0x00]<br>
+// VI:   v_add_f64 v[0:1], v[2:3], |v[5:6]| ; encoding: [0x00,0x02,0x80,0xd2,0x02,0x0b,0x02,0x00]<br>
+<br>
+v_add_f64 v[0:1], -v[2:3], |v[5:6]| clamp mul:4<br>
+// SICI: v_add_f64 v[0:1], -v[2:3], |v[5:6]| clamp mul:4 ; encoding: [0x00,0x0a,0xc8,0xd2,0x02,0x0b,0x02,0x30]<br>
+// VI:   v_add_f64 v[0:1], -v[2:3], |v[5:6]| clamp mul:4 ; encoding: [0x00,0x82,0x80,0xd2,0x02,0x0b,0x02,0x30]<br>
+<br>
+v_add_f64_e64 v[0:1], -v[2:3], |v[5:6]| clamp mul:4<br>
+// SICI: v_add_f64 v[0:1], -v[2:3], |v[5:6]| clamp mul:4 ; encoding: [0x00,0x0a,0xc8,0xd2,0x02,0x0b,0x02,0x30]<br>
+// VI:   v_add_f64 v[0:1], -v[2:3], |v[5:6]| clamp mul:4 ; encoding: [0x00,0x82,0x80,0xd2,0x02,0x0b,0x02,0x30]<br>
<br>
<br>
<br>
_______________________________________________<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/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div></div>
</div>