[Hexagon] Disallow using the same register for Vy/Vx in vdeal/vshuff
authorAlexey Karyakin <akaryaki@quicinc.com>
Wed, 1 Feb 2023 15:18:31 +0000 (07:18 -0800)
committerKrzysztof Parzyszek <kparzysz@quicinc.com>
Wed, 1 Feb 2023 15:29:03 +0000 (07:29 -0800)
Non-assignment forms of vshuff and vdeal use the first two registers
(Vy, Vx) as both inputs and outputs. It is not valid to use the same
register for both Vy and Vx. The double-write error was not detected
previously because of a special case, which is not actually necessary.

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

llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
llvm/test/MC/Hexagon/PacketRules/hvx_vshuff_vdeal.s [new file with mode: 0644]
llvm/test/MC/Hexagon/PacketRules/hvx_vshuff_vdeal_dup.s [new file with mode: 0644]
llvm/test/MC/Hexagon/extensions/v67_hvx.s

index 6fbe940..080f71e 100644 (file)
@@ -178,10 +178,6 @@ void HexagonMCChecker::init(MCInst const &MCI) {
         // TODO: relies on the impossibility of a current and a temporary loads
         // in the same packet.
         TmpDefs.insert(*SRI);
-      else if (i <= 1 && HexagonMCInstrInfo::hasNewValue2(MCII, MCI))
-        // vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and
-        // destination registers with this instruction. same for vdeal(Vx,Vy,Rx)
-        Uses.insert(*SRI);
       else if (!IgnoreTmpDst)
         Defs[*SRI].insert(PredSense(PredReg, isTrue));
     }
diff --git a/llvm/test/MC/Hexagon/PacketRules/hvx_vshuff_vdeal.s b/llvm/test/MC/Hexagon/PacketRules/hvx_vshuff_vdeal.s
new file mode 100644 (file)
index 0000000..fba4aec
--- /dev/null
@@ -0,0 +1,7 @@
+# RUN: not llvm-mc -arch=hexagon -mv65 -mhvx -filetype=obj -o 1.o %s 2>&1 | FileCheck --implicit-check-not=error %s
+
+{ v1 = v2; vshuff(v1,v3,r0) }
+# CHECK: error: register `V1' modified more than once
+
+{ v4 = v3; vdeal(v6,v4,r0) }
+# CHECK: error: register `V4' modified more than once
diff --git a/llvm/test/MC/Hexagon/PacketRules/hvx_vshuff_vdeal_dup.s b/llvm/test/MC/Hexagon/PacketRules/hvx_vshuff_vdeal_dup.s
new file mode 100644 (file)
index 0000000..a435511
--- /dev/null
@@ -0,0 +1,7 @@
+# RUN: not llvm-mc -arch=hexagon -mv65 -mhvx -filetype=obj %s 2>&1 | FileCheck %s
+
+{ vshuff(v0,v0,r0) }
+# CHECK: error: register `V0' modified more than once
+
+{ vdeal(v1,v1,r0) }
+# CHECK: error: register `V1' modified more than once
index fb72697..2b1923c 100644 (file)
 
 //  V6_vdeal
 //  vdeal(Vy32,Vx32,Rt32)
-    vdeal(v0,v0,r0)
-# CHECK-NEXT: 19e0e040 { vdeal(v0,v0,r0) }
+    vdeal(v0,v1,r0)
+# CHECK-NEXT: 19e0e041 { vdeal(v0,v1,r0) }
 
 //  V6_vdealb
 //  Vd32.b=vdeal(Vu32.b)
 
 //  V6_vshuff
 //  vshuff(Vy32,Vx32,Rt32)
-    vshuff(v0,v0,r0)
-# CHECK-NEXT: 19e0e020 { vshuff(v0,v0,r0) }
+    vshuff(v0,v1,r0)
+# CHECK-NEXT: 19e0e021 { vshuff(v0,v1,r0) }
 
 //  V6_vshuffb
 //  Vd32.b=vshuff(Vu32.b)