[PATCH] D22011: [SystemZ] Generate fewer instructions for (sub <constant>, x)

Assem Bsoul via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 5 13:42:11 PDT 2016


assem created this revision.
assem added reviewers: uweigand, zhanjunl.
assem added a subscriber: llvm-commits.

Created patterns to match subtraction of a variable from a constant to reduce the number of instructions and needed registers. The idea is to load the complement and use addition.
For example, for (sub i64 63, x):

before the change, the following is generated:
```
        lghi    %r0, 63
        sgr     %r0, %r2
        lgr     %r2, %r0
        br      %r14
```

after the change, the following is generated (less instructions):
```
       lcgr    %r2, %r2
        aghi    %r2, 63
```


http://reviews.llvm.org/D22011

Files:
  lib/Target/SystemZ/SystemZInstrInfo.td
  test/CodeGen/SystemZ/int-sub-10.ll

Index: test/CodeGen/SystemZ/int-sub-10.ll
===================================================================
--- /dev/null
+++ test/CodeGen/SystemZ/int-sub-10.ll
@@ -0,0 +1,53 @@
+; Test of subtraction that involves a constant as the first operand
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
+
+; Check AGHI highest immediate value.
+define i64 @f1(i64 %a) {
+; CHECK-LABEL: f1:
+; CHECK: lcgr %r2, %r2
+; CHECK: aghi %r2, 32767
+; CHECK: br %r14
+  %sub = sub i64 32767, %a
+  ret i64 %sub
+}
+
+; Check AGFI immediate value that cannot fit in AGHI.
+define i64 @f2(i64 %a) {
+; CHECK-LABEL: f2:
+; CHECK: lcgr %r2, %r2
+; CHECK: agfi %r2, 32768
+; CHECK: br %r14
+  %sub = sub i64 32768, %a
+  ret i64 %sub
+}
+
+; Check AGFI highest immediate value.
+define i64 @f3(i64 %a) {
+; CHECK-LABEL: f3:
+; CHECK: lcgr %r2, %r2
+; CHECK: agfi %r2, 2147483647
+; CHECK: br %r14
+  %sub = sub i64 2147483647, %a
+  ret i64 %sub
+}
+
+; Check ALGFI immediate value that cannot fit in AGFI.
+define i64 @f4(i64 %a) {
+; CHECK-LABEL: f4:
+; CHECK: lcgr %r2, %r2
+; CHECK: algfi %r2, 2147483648
+; CHECK: br %r14
+  %sub = sub i64 2147483648, %a
+  ret i64 %sub
+}
+
+; Check ALGFI highest immediate value.
+define i64 @f5(i64 %a) {
+; CHECK-LABEL: f5:
+; CHECK: lcgr %r2, %r2
+; CHECK: algfi %r2, 4294967295
+; CHECK: br %r14
+  %sub = sub i64 4294967295, %a
+  ret i64 %sub
+}
Index: lib/Target/SystemZ/SystemZInstrInfo.td
===================================================================
--- lib/Target/SystemZ/SystemZInstrInfo.td
+++ lib/Target/SystemZ/SystemZInstrInfo.td
@@ -1685,6 +1685,17 @@
 def : Pat<(and (xor GR64:$x, (i64 -1)), GR64:$y),
                           (XGR GR64:$y, (NGR GR64:$y, GR64:$x))>;

+// Generate fewer instructions for (sub <constant>, x) if the constant can fit
+// in immediate field.
+def : Pat<(sub imm64sx16:$imm, GR64:$x),
+                     (AGHI (LCGR GR64:$x), imm64sx16:$imm)>;
+
+def : Pat<(sub imm64sx32:$imm, GR64:$x),
+                     (AGFI (LCGR GR64:$x), imm64sx32:$imm)>;
+
+def : Pat<(sub imm64zx32:$imm, GR64:$x),
+                     (ALGFI (LCGR GR64:$x), imm64zx32:$imm)>;
+
 // Shift/rotate instructions only use the last 6 bits of the second operand
 // register, so we can safely use NILL (16 fewer bits than NILF) to only AND the
 // last 16 bits.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22011.62782.patch
Type: text/x-patch
Size: 2338 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160705/44e5a81c/attachment.bin>


More information about the llvm-commits mailing list