[PATCH] D23677: [AArch64] Reuse register with known value when generating csneg and csinv instructions.

Chad Rosier via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 18 10:32:41 PDT 2016


mcrosier created this revision.
mcrosier added reviewers: jmolloy, t.p.northover, ab, silviu.baranga.
mcrosier added subscribers: llvm-commits, gberry, MatzeB, evandro.
Herald added subscribers: rengolin, aemerson.

This patch allows isel to reuse a known value in a register, rather than rematerializing a constant in some cases.  Please take a look.

 Chad

https://reviews.llvm.org/D23677

Files:
  lib/Target/AArch64/AArch64ISelLowering.cpp
  test/CodeGen/AArch64/arm64-csel.ll

Index: test/CodeGen/AArch64/arm64-csel.ll
===================================================================
--- test/CodeGen/AArch64/arm64-csel.ll
+++ test/CodeGen/AArch64/arm64-csel.ll
@@ -228,3 +228,69 @@
   %inc.c = add i64 %inc, %c
   ret i64 %inc.c
 }
+
+define i32 @foo20(i32 %x) {
+entry:
+; CHECK-LABEL: foo20:
+; CHECK: cmp w[[REG:[0-9]+]], #1
+; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x1
+; CHECK: cneg w0, w[[REG]], ne
+  %cmp = icmp eq i32 %x, 1
+  %res = select i1 %cmp, i32 1, i32 -1
+  ret i32 %res
+}
+
+define i64 @foo21(i64 %x) {
+entry:
+; CHECK-LABEL: foo21:
+; CHECK: cmp x[[REG:[0-9]+]], #1
+; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x1
+; CHECK: cneg x0, x[[REG]], ne
+  %cmp = icmp eq i64 %x, 1
+  %res = select i1 %cmp, i64 1, i64 -1
+  ret i64 %res
+}
+
+define i32 @foo22(i32 %x) {
+entry:
+; CHECK-LABEL: foo22:
+; CHECK: cmp w[[REG:[0-9]+]], #3
+; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x3
+; CHECK: cneg w0, w[[REG]], ne
+  %cmp = icmp eq i32 %x, 3
+  %res = select i1 %cmp, i32 3, i32 -3
+  ret i32 %res
+}
+
+define i64 @foo23(i64 %x) {
+entry:
+; CHECK-LABEL: foo23:
+; CHECK: cmp x[[REG:[0-9]+]], #3
+; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x3
+; CHECK: cneg x0, x[[REG]], ne
+  %cmp = icmp eq i64 %x, 3
+  %res = select i1 %cmp, i64 3, i64 -3
+  ret i64 %res
+}
+
+define i32 @foo24(i32 %x) {
+entry:
+; CHECK-LABEL: foo24:
+; CHECK: cmp w[[REG:[0-9]+]], #4
+; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x4
+; CHECK: cinv w0, w[[REG]], ne
+  %cmp = icmp eq i32 %x, 4
+  %res = select i1 %cmp, i32 4, i32 -5
+  ret i32 %res
+}
+
+define i64 @foo25(i64 %x) {
+entry:
+; CHECK-LABEL: foo25:
+; CHECK: cmp x[[REG:[0-9]+]], #4
+; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x4
+; CHECK: cinv x0, x[[REG]], ne
+  %cmp = icmp eq i64 %x, 4
+  %res = select i1 %cmp, i64 4, i64 -5
+  ret i64 %res
+}
Index: lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- lib/Target/AArch64/AArch64ISelLowering.cpp
+++ lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -3995,8 +3995,14 @@
       // instead of a CSEL in that case.
       if (TrueVal == ~FalseVal) {
         Opcode = AArch64ISD::CSINV;
+        ConstantSDNode *RHSVal = dyn_cast<ConstantSDNode>(RHS);
+        if (CTVal == RHSVal && changeIntCCToAArch64CC(CC) == AArch64CC::EQ)
+          TVal = LHS;
       } else if (TrueVal == -FalseVal) {
         Opcode = AArch64ISD::CSNEG;
+        ConstantSDNode *RHSVal = dyn_cast<ConstantSDNode>(RHS);
+        if (CTVal == RHSVal && changeIntCCToAArch64CC(CC) == AArch64CC::EQ)
+          TVal = LHS;
       } else if (TVal.getValueType() == MVT::i32) {
         // If our operands are only 32-bit wide, make sure we use 32-bit
         // arithmetic for the check whether we can use CSINC. This ensures that


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23677.68561.patch
Type: text/x-patch
Size: 2761 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160818/834f1aa9/attachment.bin>


More information about the llvm-commits mailing list