[llvm] [SystemZ] Use LCGR/AGHI for i64 XOR with -1 (PR #74882)

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 8 12:03:51 PST 2023


https://github.com/JonPsson1 created https://github.com/llvm/llvm-project/pull/74882

LCGR/AGHI is a more compact way of implementing a 64-bit NOT.


>From 6219052d01fd125a9e2c683f9a05cc3b0753c5ae Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Fri, 8 Dec 2023 13:49:50 -0600
Subject: [PATCH] XOR -1 -> LCGR/AGHI

---
 .../Target/SystemZ/SystemZISelDAGToDAG.cpp    |  3 +
 llvm/lib/Target/SystemZ/SystemZInstrInfo.td   |  4 ++
 .../test/CodeGen/SystemZ/atomicrmw-nand-04.ll | 69 +++++++++----------
 llvm/test/CodeGen/SystemZ/xor-04.ll           |  4 +-
 4 files changed, 43 insertions(+), 37 deletions(-)

diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index 4cc69530db011e..0d8d5451b8136c 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -1558,6 +1558,9 @@ void SystemZDAGToDAGISel::Select(SDNode *Node) {
                 break;
           }
         }
+        // Don't split an XOR with -1 as LCGR/AGHI is more compact.
+        if (Opcode == ISD::XOR && Op1->isAllOnes())
+          break;
         if (!SystemZ::isImmLF(Val) && !SystemZ::isImmHF(Val)) {
           splitLargeImmediate(Opcode, Node, Node->getOperand(0),
                               Val - uint32_t(Val), uint32_t(Val));
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index 210e6a51b6dcbe..937e36057a6ede 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -2263,6 +2263,10 @@ let isCodeGenOnly = 1, hasSideEffects = 1 in {
 def : Pat<(and (xor GR64:$x, (i64 -1)), GR64:$y),
                           (XGR GR64:$y, (NGR GR64:$y, GR64:$x))>;
 
+// Use LCGR/AGHI for i64 xor with -1.
+def : Pat<(xor GR64:$x, (i64 -1)),
+          (AGHI (LCGR GR64:$x), (i64 -1))>;
+
 // 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.
diff --git a/llvm/test/CodeGen/SystemZ/atomicrmw-nand-04.ll b/llvm/test/CodeGen/SystemZ/atomicrmw-nand-04.ll
index 98056c9c9a012f..3ff259d5576c8e 100644
--- a/llvm/test/CodeGen/SystemZ/atomicrmw-nand-04.ll
+++ b/llvm/test/CodeGen/SystemZ/atomicrmw-nand-04.ll
@@ -9,8 +9,8 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
 ; CHECK: [[LABEL:\.[^:]*]]:
 ; CHECK: lgr %r0, %r2
 ; CHECK: ngr %r0, %r4
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r0
+; CHECK: aghi %r0, -1
 ; CHECK: csg %r2, %r0, 0(%r3)
 ; CHECK: jl [[LABEL]]
 ; CHECK: br %r14
@@ -21,8 +21,8 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
 ; Check NANDs of 1, which are done using a register.
 define i64 @f2(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f2:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihf %r0, 4294967295
 ; CHECK: oilf %r0, 4294967294
 ; CHECK: br %r14
@@ -34,8 +34,8 @@ define i64 @f3(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f3:
 ; CHECK: lg %r2, 0(%r3)
 ; CHECK: [[LABEL:\.[^:]*]]:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihf %r0, 4294967294
 ; CHECK: jl [[LABEL]]
 ; CHECK: br %r14
@@ -47,9 +47,8 @@ define i64 @f4(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f4:
 ; CHECK: lg %r2, 0(%r3)
 ; CHECK: [[LABEL:\.[^:]*]]:
-; CHECK: lgr %r0, %r2
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihf %r0, 4294967293
 ; CHECK: csg %r2, %r0, 0(%r3)
 ; CHECK: jl [[LABEL]]
@@ -60,8 +59,8 @@ define i64 @f4(i64 %dummy, ptr %src) {
 
 define i64 @f5(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f5:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihf %r0, 4294967292
 ; CHECK: oilf %r0, 4294967295
 ; CHECK: br %r14
@@ -71,8 +70,8 @@ define i64 @f5(i64 %dummy, ptr %src) {
 
 define i64 @f6(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f6:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihh %r0, 65533
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 844424930131967 seq_cst
@@ -81,8 +80,8 @@ define i64 @f6(i64 %dummy, ptr %src) {
 
 define i64 @f7(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f7:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihf %r0, 4294901759
 ; CHECK: oilf %r0, 4294967295
 ; CHECK: br %r14
@@ -92,8 +91,8 @@ define i64 @f7(i64 %dummy, ptr %src) {
 
 define i64 @f8(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f8:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oill %r0, 5
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -6 seq_cst
@@ -102,8 +101,8 @@ define i64 @f8(i64 %dummy, ptr %src) {
 
 define i64 @f9(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f9:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oill %r0, 65533
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -65534 seq_cst
@@ -112,8 +111,8 @@ define i64 @f9(i64 %dummy, ptr %src) {
 
 define i64 @f10(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f10:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oilf %r0, 65537
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -65538 seq_cst
@@ -122,8 +121,8 @@ define i64 @f10(i64 %dummy, ptr %src) {
 
 define i64 @f11(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f11:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oilh %r0, 5
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -327681 seq_cst
@@ -132,8 +131,8 @@ define i64 @f11(i64 %dummy, ptr %src) {
 
 define i64 @f12(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f12:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oilh %r0, 65533
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -4294770689 seq_cst
@@ -142,8 +141,8 @@ define i64 @f12(i64 %dummy, ptr %src) {
 
 define i64 @f13(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f13:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oilf %r0, 4294967293
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -4294967294 seq_cst
@@ -152,8 +151,8 @@ define i64 @f13(i64 %dummy, ptr %src) {
 
 define i64 @f14(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f14:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihl %r0, 5
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -21474836481 seq_cst
@@ -162,8 +161,8 @@ define i64 @f14(i64 %dummy, ptr %src) {
 
 define i64 @f15(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f15:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihl %r0, 65533
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -281462091808769 seq_cst
@@ -172,8 +171,8 @@ define i64 @f15(i64 %dummy, ptr %src) {
 
 define i64 @f16(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f16:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihh %r0, 5
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -1407374883553281 seq_cst
@@ -182,8 +181,8 @@ define i64 @f16(i64 %dummy, ptr %src) {
 
 define i64 @f17(i64 %dummy, ptr %src) {
 ; CHECK-LABEL: f17:
-; CHECK: xihf %r0, 4294967295
-; CHECK: xilf %r0, 4294967295
+; CHECK: lcgr %r0, %r2
+; CHECK: aghi %r0, -1
 ; CHECK: oihf %r0, 65537
 ; CHECK: br %r14
   %res = atomicrmw nand ptr %src, i64 -281479271677953 seq_cst
diff --git a/llvm/test/CodeGen/SystemZ/xor-04.ll b/llvm/test/CodeGen/SystemZ/xor-04.ll
index 44f0a4cc39d0c3..ce5b76507b0dc2 100644
--- a/llvm/test/CodeGen/SystemZ/xor-04.ll
+++ b/llvm/test/CodeGen/SystemZ/xor-04.ll
@@ -61,8 +61,8 @@ define i64 @f6(i64 %a) {
 ; Check full bitwise negation
 define i64 @f7(i64 %a) {
 ; CHECK-LABEL: f7:
-; CHECK: xihf %r2, 4294967295
-; CHECK: xilf %r2, 4294967295
+; CHECK: lcgr %r2, %r2
+; CHECK: aghi %r2, -1
 ; CHECK: br %r14
   %xor = xor i64 %a, -1
   ret i64 %xor



More information about the llvm-commits mailing list