[llvm] r325459 - [AArch64] Coalesce Copy Zero during instruction selection

Haicheng Wu via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 18 05:51:33 PST 2018


Author: haicheng
Date: Sun Feb 18 05:51:33 2018
New Revision: 325459

URL: http://llvm.org/viewvc/llvm-project?rev=325459&view=rev
Log:
[AArch64] Coalesce Copy Zero during instruction selection

Add special case for copy of zero to avoid a double copy.

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

Added:
    llvm/trunk/test/CodeGen/AArch64/copy-zero-reg.ll
Modified:
    llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
    llvm/trunk/test/CodeGen/AArch64/arm64-addr-type-promotion.ll
    llvm/trunk/test/CodeGen/AArch64/arm64-cse.ll
    llvm/trunk/test/CodeGen/AArch64/i128-fast-isel-fallback.ll

Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp?rev=325459&r1=325458&r2=325459&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp Sun Feb 18 05:51:33 2018
@@ -2777,7 +2777,35 @@ void AArch64DAGToDAGISel::Select(SDNode
     }
     break;
   }
-
+  case ISD::CopyToReg: {
+    // Special case for copy of zero to avoid a double copy.
+    SDNode *CopyVal = Node->getOperand(2).getNode();
+    ConstantSDNode *CopyValConst = dyn_cast<ConstantSDNode>(CopyVal);
+    if (!CopyValConst || !CopyValConst->isNullValue())
+      break;
+    const SDValue &Dest = Node->getOperand(1);
+    if (!TargetRegisterInfo::isVirtualRegister(
+            cast<RegisterSDNode>(Dest)->getReg()))
+      break;
+    unsigned ZeroReg;
+    EVT ZeroVT = CopyValConst->getValueType(0);
+    if (ZeroVT == MVT::i32)
+      ZeroReg = AArch64::WZR;
+    else if (ZeroVT == MVT::i64)
+      ZeroReg = AArch64::XZR;
+    else
+      break;
+    unsigned NumOperands = Node->getNumOperands();
+    SDValue ZeroRegVal = CurDAG->getRegister(ZeroReg, ZeroVT);
+    // Replace the source operand (#0) with ZeroRegVal.
+    SDValue Ops[] = {Node->getOperand(0), Node->getOperand(1), ZeroRegVal,
+                     (NumOperands == 4) ? Node->getOperand(3) : SDValue()};
+    SDValue New =
+        CurDAG->getNode(ISD::CopyToReg, SDLoc(Node), Node->getVTList(),
+                        makeArrayRef(Ops, NumOperands));
+    ReplaceNode(Node, New.getNode());
+    return;
+  }
   case ISD::FrameIndex: {
     // Selects to ADDXri FI, 0 which in turn will become ADDXri SP, imm.
     int FI = cast<FrameIndexSDNode>(Node)->getIndex();

Modified: llvm/trunk/test/CodeGen/AArch64/arm64-addr-type-promotion.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-addr-type-promotion.ll?rev=325459&r1=325458&r2=325459&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/arm64-addr-type-promotion.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/arm64-addr-type-promotion.ll Sun Feb 18 05:51:33 2018
@@ -28,6 +28,7 @@ define zeroext i8 @fullGtU(i32 %i1, i32
 ; Next BB
 ; CHECK: ldrb [[LOADEDVAL3:w[0-9]+]], {{\[}}[[BLOCKBASE1]], #2]
 ; CHECK-NEXT: ldrb [[LOADEDVAL4:w[0-9]+]], {{\[}}[[BLOCKBASE2]], #2]
+; CHECK-NEXT: mov w0, wzr
 ; CHECK-NEXT: cmp [[LOADEDVAL3]], [[LOADEDVAL4]]
 entry:
   %idxprom = sext i32 %i1 to i64

Modified: llvm/trunk/test/CodeGen/AArch64/arm64-cse.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-cse.ll?rev=325459&r1=325458&r2=325459&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/arm64-cse.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/arm64-cse.ll Sun Feb 18 05:51:33 2018
@@ -10,7 +10,7 @@ entry:
 ; CHECK: subs
 ; CHECK-NOT: cmp
 ; CHECK-NOT: sub
-; CHECK: b.ge
+; CHECK: b.lt
 ; CHECK: sub
 ; CHECK: sub
 ; CHECK-NOT: sub

Added: llvm/trunk/test/CodeGen/AArch64/copy-zero-reg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/copy-zero-reg.ll?rev=325459&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/copy-zero-reg.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/copy-zero-reg.ll Sun Feb 18 05:51:33 2018
@@ -0,0 +1,47 @@
+; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-none-linux-gnu | FileCheck %s
+
+; Verify there is no tiny block having only one mov wzr instruction between for.body.lr.ph and sw.epilog.loopexit
+define void @unroll_by_2(i32 %trip_count, i32* %p) {
+; CHECK-LABEL: unroll_by_2
+; CHECK: // %for.body.lr.ph
+; CHECK:     mov   w{{[0-9]+}}, wzr
+; CHECK:     b.eq
+; CHECK-NOT: mov   w{{[0-9]+}}, wzr
+; CHECK: // %for.body.lr.ph.new
+; CHECK: // %for.body
+; CHECK: // %sw.epilog.loopexit
+; CHECK: // %for.body.epil
+; CHECK: // %exit
+; CHECK-NEXT:   ret
+for.body.lr.ph:
+  %xtraiter = and i32 %trip_count, 1
+  %cmp = icmp eq i32 %trip_count, 1
+  br i1 %cmp, label %sw.epilog.loopexit, label %for.body.lr.ph.new
+
+for.body.lr.ph.new:
+  %unroll_iter = sub nsw i32 %trip_count, %xtraiter
+  br label %for.body
+
+for.body:
+  %indvars = phi i32 [ 0, %for.body.lr.ph.new ], [ %indvars.next, %for.body ]
+  %niter = phi i32 [ %unroll_iter, %for.body.lr.ph.new ], [ %niter.nsub, %for.body ]
+  %array = getelementptr inbounds i32, i32 * %p, i32 %indvars
+  store  i32 %niter, i32* %array
+  %indvars.next = add i32 %indvars, 2
+  %niter.nsub = add i32 %niter, -2
+  %niter.ncmp = icmp eq i32 %niter.nsub, 0
+  br i1 %niter.ncmp, label %sw.epilog.loopexit, label %for.body
+
+sw.epilog.loopexit:
+  %indvars.unr = phi i32 [ 0, %for.body.lr.ph ], [ %indvars.next, %for.body ]
+  %lcmp.mod = icmp eq i32 %xtraiter, 0
+  br i1 %lcmp.mod, label %exit, label %for.body.epil
+
+for.body.epil:
+  %array.epil = getelementptr inbounds i32, i32* %p, i32 %indvars.unr
+  store  i32 %indvars.unr, i32* %array.epil
+  br label %exit
+
+exit:
+  ret void
+}

Modified: llvm/trunk/test/CodeGen/AArch64/i128-fast-isel-fallback.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/i128-fast-isel-fallback.ll?rev=325459&r1=325458&r2=325459&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/i128-fast-isel-fallback.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/i128-fast-isel-fallback.ll Sun Feb 18 05:51:33 2018
@@ -10,7 +10,7 @@ define void @test1() {
 ; registers that make up the i128 pair
 
 ; CHECK:  mov  x0, xzr
-; CHECK:  mov  x1, x0
+; CHECK:  mov  x1, xzr 
 ; CHECK:  bl  _test2
 
 }




More information about the llvm-commits mailing list