<div dir="ltr"><div dir="ltr"><div dir="ltr">The lit internal shell does not support '|&':</div><div dir="ltr"><br><div><a href="http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/3329">http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/3329</a><br></div><div><div>FAIL: LLVM :: CodeGen/AArch64/misched-fusion-arith-logic.mir (5654 of 29326)</div><div>******************** TEST 'LLVM :: CodeGen/AArch64/misched-fusion-arith-logic.mir' FAILED ********************</div><div>shell parser error on: ": 'RUN: at line 1';   C:\\b\\slave\\clang-x64-windows-msvc\\build\\build\\stage1\\bin\\llc.EXE -o - C:\\b\\slave\\clang-x64-windows-msvc\\build\\llvm.src\\test\\CodeGen\\AArch64\\misched-fusion-arith-logic.mir -mtriple aarch64-unknown -mattr=fuse-arith-logic -run-pass=machine-scheduler -misched-print-dags |& C:\\b\\slave\\clang-x64-windows-msvc\\build\\build\\stage1\\bin\\FileCheck.EXE C:\\b\\slave\\clang-x64-windows-msvc\\build\\llvm.src\\test\\CodeGen\\AArch64\\misched-fusion-arith-logic.mir"</div><div>********************</div></div><div><br></div><div>I'll submit a quick fix.</div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jan 14, 2019 at 3:58 PM Evandro Menezes via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: evandro<br>
Date: Mon Jan 14 15:54:36 2019<br>
New Revision: 351139<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=351139&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=351139&view=rev</a><br>
Log:<br>
[AArch64] Add new target feature to fuse arithmetic and logic operations<br>
<br>
This feature enables the fusion of some arithmetic and logic instructions<br>
together.<br>
<br>
Differential revision: <a href="https://reviews.llvm.org/D56572" rel="noreferrer" target="_blank">https://reviews.llvm.org/D56572</a><br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/AArch64/misched-fusion-arith-logic.mir<br>
Modified:<br>
    llvm/trunk/lib/Target/AArch64/AArch64.td<br>
    llvm/trunk/lib/Target/AArch64/AArch64MacroFusion.cpp<br>
    llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64.td?rev=351139&r1=351138&r2=351139&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64.td?rev=351139&r1=351138&r2=351139&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64.td (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64.td Mon Jan 14 15:54:36 2019<br>
@@ -188,14 +188,18 @@ def FeatureFuseAES : SubtargetFeature<<br>
     "fuse-aes", "HasFuseAES", "true",<br>
     "CPU fuses AES crypto operations">;<br>
<br>
-def FeatureFuseCryptoEOR : SubtargetFeature<<br>
-    "fuse-crypto-eor", "HasFuseCryptoEOR", "true",<br>
-    "CPU fuses AES/PMULL and EOR operations">;<br>
+def FeatureFuseArithmeticLogic : SubtargetFeature<<br>
+    "fuse-arith-logic", "HasFuseArithmeticLogic", "true",<br>
+    "CPU fuses arithmetic and logic operations">;<br>
<br>
 def FeatureFuseCCSelect : SubtargetFeature<<br>
     "fuse-csel", "HasFuseCCSelect", "true",<br>
     "CPU fuses conditional select operations">;<br>
<br>
+def FeatureFuseCryptoEOR : SubtargetFeature<<br>
+    "fuse-crypto-eor", "HasFuseCryptoEOR", "true",<br>
+    "CPU fuses AES/PMULL and EOR operations">;<br>
+<br>
 def FeatureFuseLiterals : SubtargetFeature<<br>
     "fuse-literals", "HasFuseLiterals", "true",<br>
     "CPU fuses literal generation operations">;<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64MacroFusion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64MacroFusion.cpp?rev=351139&r1=351138&r2=351139&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64MacroFusion.cpp?rev=351139&r1=351138&r2=351139&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64MacroFusion.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64MacroFusion.cpp Mon Jan 14 15:54:36 2019<br>
@@ -270,7 +270,107 @@ static bool isCCSelectPair(const Machine<br>
   return false;<br>
 }<br>
<br>
-/// Check if the instr pair, FirstMI and SecondMI, should be fused<br>
+// Arithmetic and logic.<br>
+static bool isArithmeticLogicPair(const MachineInstr *FirstMI,<br>
+                                  const MachineInstr &SecondMI) {<br>
+  if (AArch64InstrInfo::hasShiftedReg(SecondMI))<br>
+    return false;<br>
+<br>
+  switch (SecondMI.getOpcode()) {<br>
+  // Arithmetic<br>
+  case AArch64::ADDWrr:<br>
+  case AArch64::ADDXrr:<br>
+  case AArch64::SUBWrr:<br>
+  case AArch64::SUBXrr:<br>
+  case AArch64::ADDWrs:<br>
+  case AArch64::ADDXrs:<br>
+  case AArch64::SUBWrs:<br>
+  case AArch64::SUBXrs:<br>
+  // Logic<br>
+  case AArch64::ANDWrr:<br>
+  case AArch64::ANDXrr:<br>
+  case AArch64::BICWrr:<br>
+  case AArch64::BICXrr:<br>
+  case AArch64::EONWrr:<br>
+  case AArch64::EONXrr:<br>
+  case AArch64::EORWrr:<br>
+  case AArch64::EORXrr:<br>
+  case AArch64::ORNWrr:<br>
+  case AArch64::ORNXrr:<br>
+  case AArch64::ORRWrr:<br>
+  case AArch64::ORRXrr:<br>
+  case AArch64::ANDWrs:<br>
+  case AArch64::ANDXrs:<br>
+  case AArch64::BICWrs:<br>
+  case AArch64::BICXrs:<br>
+  case AArch64::EONWrs:<br>
+  case AArch64::EONXrs:<br>
+  case AArch64::EORWrs:<br>
+  case AArch64::EORXrs:<br>
+  case AArch64::ORNWrs:<br>
+  case AArch64::ORNXrs:<br>
+  case AArch64::ORRWrs:<br>
+  case AArch64::ORRXrs:<br>
+    // Assume the 1st instr to be a wildcard if it is unspecified.<br>
+    if (FirstMI == nullptr)<br>
+      return true;<br>
+<br>
+    // Arithmetic<br>
+    switch (FirstMI->getOpcode()) {<br>
+    case AArch64::ADDWrr:<br>
+    case AArch64::ADDXrr:<br>
+    case AArch64::ADDSWrr:<br>
+    case AArch64::ADDSXrr:<br>
+    case AArch64::SUBWrr:<br>
+    case AArch64::SUBXrr:<br>
+    case AArch64::SUBSWrr:<br>
+    case AArch64::SUBSXrr:<br>
+      return true;<br>
+    case AArch64::ADDWrs:<br>
+    case AArch64::ADDXrs:<br>
+    case AArch64::ADDSWrs:<br>
+    case AArch64::ADDSXrs:<br>
+    case AArch64::SUBWrs:<br>
+    case AArch64::SUBXrs:<br>
+    case AArch64::SUBSWrs:<br>
+    case AArch64::SUBSXrs:<br>
+      return !AArch64InstrInfo::hasShiftedReg(*FirstMI);<br>
+    }<br>
+    break;<br>
+<br>
+  // Arithmetic, setting flags.<br>
+  case AArch64::ADDSWrr:<br>
+  case AArch64::ADDSXrr:<br>
+  case AArch64::SUBSWrr:<br>
+  case AArch64::SUBSXrr:<br>
+  case AArch64::ADDSWrs:<br>
+  case AArch64::ADDSXrs:<br>
+  case AArch64::SUBSWrs:<br>
+  case AArch64::SUBSXrs:<br>
+    // Assume the 1st instr to be a wildcard if it is unspecified.<br>
+    if (FirstMI == nullptr)<br>
+      return true;<br>
+<br>
+    // Arithmetic, not setting flags.<br>
+    switch (FirstMI->getOpcode()) {<br>
+    case AArch64::ADDWrr:<br>
+    case AArch64::ADDXrr:<br>
+    case AArch64::SUBWrr:<br>
+    case AArch64::SUBXrr:<br>
+      return true;<br>
+    case AArch64::ADDWrs:<br>
+    case AArch64::ADDXrs:<br>
+    case AArch64::SUBWrs:<br>
+    case AArch64::SUBXrs:<br>
+      return !AArch64InstrInfo::hasShiftedReg(*FirstMI);<br>
+    }<br>
+    break;<br>
+  }<br>
+<br>
+  return false;<br>
+}<br>
+<br>
+/// \brief Check if the instr pair, FirstMI and SecondMI, should be fused<br>
 /// together. Given SecondMI, when FirstMI is unspecified, then check if<br>
 /// SecondMI may be part of a fused pair at all.<br>
 static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,<br>
@@ -295,6 +395,8 @@ static bool shouldScheduleAdjacent(const<br>
     return true;<br>
   if (ST.hasFuseCCSelect() && isCCSelectPair(FirstMI, SecondMI))<br>
     return true;<br>
+  if (ST.hasFuseArithmeticLogic() && isArithmeticLogicPair(FirstMI, SecondMI))<br>
+    return true;<br>
<br>
   return false;<br>
 }<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=351139&r1=351138&r2=351139&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=351139&r1=351138&r2=351139&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h Mon Jan 14 15:54:36 2019<br>
@@ -166,8 +166,9 @@ protected:<br>
   bool HasArithmeticCbzFusion = false;<br>
   bool HasFuseAddress = false;<br>
   bool HasFuseAES = false;<br>
-  bool HasFuseCryptoEOR = false;<br>
+  bool HasFuseArithmeticLogic = false;<br>
   bool HasFuseCCSelect = false;<br>
+  bool HasFuseCryptoEOR = false;<br>
   bool HasFuseLiterals = false;<br>
   bool DisableLatencySchedHeuristic = false;<br>
   bool UseRSqrt = false;<br>
@@ -311,14 +312,16 @@ public:<br>
   bool hasArithmeticCbzFusion() const { return HasArithmeticCbzFusion; }<br>
   bool hasFuseAddress() const { return HasFuseAddress; }<br>
   bool hasFuseAES() const { return HasFuseAES; }<br>
-  bool hasFuseCryptoEOR() const { return HasFuseCryptoEOR; }<br>
+  bool hasFuseArithmeticLogic() const { return HasFuseArithmeticLogic; }<br>
   bool hasFuseCCSelect() const { return HasFuseCCSelect; }<br>
+  bool hasFuseCryptoEOR() const { return HasFuseCryptoEOR; }<br>
   bool hasFuseLiterals() const { return HasFuseLiterals; }<br>
<br>
   /// Return true if the CPU supports any kind of instruction fusion.<br>
   bool hasFusion() const {<br>
     return hasArithmeticBccFusion() || hasArithmeticCbzFusion() ||<br>
-           hasFuseAES() || hasFuseCCSelect() || hasFuseLiterals();<br>
+           hasFuseAES() || hasFuseArithmeticLogic() ||<br>
+           hasFuseCCSelect() || hasFuseLiterals();<br>
   }<br>
<br>
   bool useRSqrt() const { return UseRSqrt; }<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/misched-fusion-arith-logic.mir<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/misched-fusion-arith-logic.mir?rev=351139&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/misched-fusion-arith-logic.mir?rev=351139&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/misched-fusion-arith-logic.mir (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/misched-fusion-arith-logic.mir Mon Jan 14 15:54:36 2019<br>
@@ -0,0 +1,111 @@<br>
+# RUN: llc -o - %s -mtriple aarch64-unknown -mattr=fuse-arith-logic -run-pass=machine-scheduler -misched-print-dags |& FileCheck %s<br>
+# REQUIRES: asserts<br>
+<br>
+---<br>
+name: arith<br>
+body: |<br>
+  bb.0.entry:<br>
+    %0:gpr32 = SUBWrr undef $w0, undef $w1<br>
+    %1:gpr32 = ADDWrr undef $w1, undef $w2<br>
+    %2:gpr32 = SUBWrs %0, undef $w2, 0<br>
+    %3:gpr32 = ADDWrs %1, undef $w3, 0<br>
+<br>
+    ; CHECK: SU(0): %0:gpr32 = SUBWrr undef $w0, undef $w1<br>
+    ; CHECK: Successors:<br>
+    ; CHECK: SU(2): Ord  Latency=0 Cluster<br>
+    ; CHECK: SU(1): %1:gpr32 = ADDWrr undef $w1, undef $w2<br>
+    ; CHECK: Successors:<br>
+    ; CHECK: SU(3): Ord  Latency=0 Cluster<br>
+    ; CHECK: SU(2): dead %2:gpr32 = SUBWrs %0:gpr32, undef $w2, 0<br>
+    ; CHECK: Predecessors:<br>
+    ; CHECK: SU(0): Ord  Latency=0 Cluster<br>
+    ; CHECK: SU(3): dead %3:gpr32 = ADDWrs %1:gpr32, undef $w3, 0<br>
+    ; CHECK: Predecessors:<br>
+    ; CHECK: SU(1): Ord  Latency=0 Cluster<br>
+...<br>
+---<br>
+name: compare<br>
+body: |<br>
+  bb.0.entry:<br>
+    %0:gpr64 = ADDXrr undef $x0, undef $x1<br>
+    %1:gpr64 = SUBXrs undef $x1, undef $x2, 0<br>
+    %2:gpr64 = ADDSXrr %0, undef $x3, implicit-def $nzcv<br>
+    %3:gpr64 = SUBSXrs %1, undef $x4, 0, implicit-def $nzcv<br>
+<br>
+    ; CHECK: SU(0): %0:gpr64 = ADDXrr undef $x0, undef $x1<br>
+    ; CHECK: Successors:<br>
+    ; CHECK: SU(2): Ord  Latency=0 Cluster<br>
+    ; CHECK: SU(1): %1:gpr64 = SUBXrs undef $x1, undef $x2, 0<br>
+    ; CHECK: Successors:<br>
+    ; CHECK: SU(3): Ord  Latency=0 Cluster<br>
+    ; CHECK: SU(2): dead %2:gpr64 = ADDSXrr %0:gpr64, undef $x3, implicit-def $nzcv<br>
+    ; CHECK: Predecessors:<br>
+    ; CHECK: SU(0): Ord  Latency=0 Cluster<br>
+    ; CHECK: SU(3): dead %3:gpr64 = SUBSXrs %1:gpr64, undef $x4, 0, implicit-def $nzcv<br>
+    ; CHECK: Predecessors:<br>
+    ; CHECK: SU(1): Ord  Latency=0 Cluster<br>
+...<br>
+---<br>
+name: logic<br>
+body: |<br>
+  bb.0.entry:<br>
+    %0:gpr32 = ADDWrr undef $w0, undef $w1<br>
+    %1:gpr64 = SUBXrs undef $x1, undef $x2, 0<br>
+    %3:gpr32 = ANDWrs %0, undef $w3, 0<br>
+    %4:gpr64 = ORRXrr %1, undef $x4<br>
+<br>
+    ; CHECK: SU(0): %0:gpr32 = ADDWrr undef $w0, undef $w1<br>
+    ; CHECK: Successors:<br>
+    ; CHECK: SU(2): Ord  Latency=0 Cluster<br>
+    ; CHECK: SU(1): %1:gpr64 = SUBXrs undef $x1, undef $x2, 0<br>
+    ; CHECK: Successors:<br>
+    ; CHECK: SU(3): Ord  Latency=0 Cluster<br>
+    ; CHECK: SU(2): dead %2:gpr32 = ANDWrs %0:gpr32, undef $w3, 0<br>
+    ; CHECK: Predecessors:<br>
+    ; CHECK: SU(0): Ord  Latency=0 Cluster<br>
+    ; CHECK: SU(3): dead %3:gpr64 = ORRXrr %1:gpr64, undef $x4<br>
+    ; CHECK: Predecessors:<br>
+    ; CHECK: SU(1): Ord  Latency=0 Cluster<br>
+...<br>
+---<br>
+name: nope<br>
+body: |<br>
+  bb.0.entry:<br>
+    ; Shifted register.<br>
+    %0:gpr32 = SUBWrr undef $w0, undef $w1<br>
+    %1:gpr32 = SUBWrs %0, undef $w2, 1<br>
+    ; CHECKSU(0)%0:gpr32 = SUBWrr undef $w0, undef $w1<br>
+    ; CHECKSuccessors:<br>
+    ; CHECK-NOTSU(1)Ord  Latency=0 Cluster<br>
+    ; CHECKSU(1)dead %1:gpr32 = SUBWrs %0:gpr32, undef $w2, 1<br>
+<br>
+    ; Multiple successors.<br>
+    %2:gpr64 = ADDXrr undef $x0, undef $x1<br>
+    %3:gpr32 = EXTRACT_SUBREG %2, %subreg.sub_32<br>
+    %4:gpr32 = ANDWrs %3, undef $w2, 0<br>
+    %5:gpr64 = ADDSXrr %2, undef $x3, implicit-def $nzcv<br>
+    ; CHECKSU(2)%2:gpr64 = ADDXrr undef $x0, undef $x1<br>
+    ; CHECKSuccessors:<br>
+    ; CHECK-NOTSU(3)Ord  Latency=0 Cluster<br>
+    ; CHECKSU(5)Ord  Latency=0 Cluster<br>
+    ; CHECKSU(3)%3:gpr32 = EXTRACT_SUBREG %2:gpr64, %subreg.sub_32<br>
+    ; CHECKSU(5)dead %5:gpr64 = ADDSXrr %2:gpr64, undef $x3, implicit-def $nzcv<br>
+<br>
+    ; Different register sizes.<br>
+    %6:gpr32 = SUBWrr undef $w0, undef $w1<br>
+    %7:gpr64 = ADDXrr undef $x1, undef $x2<br>
+    %8:gpr64 = SUBXrr %7, undef $x3<br>
+    %9:gpr32 = ADDWrr %6, undef $w4<br>
+    ; CHECKSU(6)%6:gpr32 = SUBWrr undef $w0, undef $w1<br>
+    ; CHECKSuccessors:<br>
+    ; CHECK-NOTSU(8)Ord  Latency=0 Cluster<br>
+    ; CHECKSU(7)%7:gpr64 = ADDXrr undef $x1, undef $x2<br>
+    ; CHECKSuccessors:<br>
+    ; CHECK-NOTSU(9)Ord  Latency=0 Cluster<br>
+    ; CHECKSU(8)dead %8:gpr64 = SUBXrr %7:gpr64, undef $x3<br>
+    ; CHECKPredecessors:<br>
+    ; CHECKSU(7)Ord  Latency=0 Cluster<br>
+    ; CHECKSU(9)dead %9:gpr32 = ADDWrr %6:gpr32, undef $w4<br>
+    ; CHECKPredecessors:<br>
+    ; CHECKSU(6)Ord  Latency=0 Cluster<br>
+...<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">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>