[PATCH] D42051: [ARM] Avoid having to schedule a copy between CPSR and GPR in Thumb1 mode

Roger Ferrer Ibanez via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 15 00:25:27 PST 2018


rogfer01 created this revision.
rogfer01 added a reviewer: efriedma.
Herald added subscribers: kristof.beyls, javed.absar, aemerson.

This is a fix for PR35836 in which for Thumb1 we avoid combining `ADDC` and `ADDE` in a way that could require a copy CPSR ↔ GPR.


Repository:
  rL LLVM

https://reviews.llvm.org/D42051

Files:
  lib/Target/ARM/ARMISelLowering.cpp
  test/CodeGen/Thumb/pr35836.ll


Index: test/CodeGen/Thumb/pr35836.ll
===================================================================
--- /dev/null
+++ test/CodeGen/Thumb/pr35836.ll
@@ -0,0 +1,51 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "thumbv5e-none-linux-gnueabi"
+
+; Function Attrs: norecurse nounwind optsize
+define void @f(i32,i32,i32,i32,i32* %x4p, i32* %x5p, i32* %x6p) {
+if.end:
+  br label %while.body
+
+while.body:
+  %ll.0100 = phi i64 [ 0, %if.end ], [ %shr32, %while.body ]
+  %add = add nuw nsw i64 %ll.0100, 0
+  %add3 = add nuw nsw i64 %add, 0
+  %shr = lshr i64 %add3, 32
+  %conv7 = zext i32 %0 to i64
+  %conv9 = zext i32 %1 to i64
+  %add10 = add nuw nsw i64 %conv9, %conv7
+  %add11 = add nuw nsw i64 %add10, %shr
+  %shr14 = lshr i64 %add11, 32
+  %conv16 = zext i32 %2 to i64
+  %conv18 = zext i32 %3 to i64
+  %add19 = add nuw nsw i64 %conv18, %conv16
+  %add20 = add nuw nsw i64 %add19, %shr14
+  %conv21 = trunc i64 %add20 to i32
+  store i32 %conv21, i32* %x6p, align 4
+  %shr23 = lshr i64 %add20, 32
+  %x4 = load i32, i32* %x4p, align 4
+  %conv25 = zext i32 %x4 to i64
+  %x5 = load i32, i32* %x5p, align 4
+  %conv27 = zext i32 %x5 to i64
+  %add28 = add nuw nsw i64 %conv27, %conv25
+  %add29 = add nuw nsw i64 %add28, %shr23
+  %shr32 = lshr i64 %add29, 32
+  br label %while.body
+
+; CHECK:	adds
+; CHECK:	adcs
+; CHECK:	adds
+; CHECK:	adcs
+; CHECK:	adds
+; CHECK:	adcs
+; CHECK:	adcs
+; CHECK:	adds
+; CHECK:	adcs
+; We need to preserve this seemingly redundant instruction otherwise copies
+; CPSR <-> GPR would be emitted and we can't always do this in Thumb1.
+; CHECK:	subs	{{r[0-9]+}}, {{r[0-9]+}}, #1
+; CHECK:	adcs
+; CHECK:	adcs
+}
Index: lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- lib/Target/ARM/ARMISelLowering.cpp
+++ lib/Target/ARM/ARMISelLowering.cpp
@@ -10117,7 +10117,30 @@
     if (LHS->getOpcode() == ARMISD::ADDE &&
         isNullConstant(LHS->getOperand(0)) &&
         isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
-      return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
+      bool StillOK = true;
+      if (Subtarget->isThumb1Only()) {
+        // In Thumb1, if C is used by a node that is reachable from one of the
+        // users of N then we may end creating a DAG that requires copying CPSR
+        // to a GPR and we can't always do this. So in this case spend some
+        // time checking if it is OK to remove this (potentially) redundant
+        // operation.
+        SDNode *C = LHS->getOperand(2).getNode();
+        for (const auto &Use : N->uses()) {
+          for (const auto &Op : Use->ops()) {
+            SDNode *OpN = Op.getNode();
+            if (OpN != N && OpN->hasPredecessor(C)) {
+              StillOK = false;
+              break;
+            }
+          }
+          if (!StillOK)
+            break;
+        }
+      }
+
+      if (StillOK) {
+        return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
+      }
     }
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42051.129808.patch
Type: text/x-patch
Size: 3091 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180115/a765e327/attachment.bin>


More information about the llvm-commits mailing list