[llvm] [PowerPC] simplify the asm of scmp builtin (PR #200024)

zhijian lin via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 9 08:30:15 PDT 2026


https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/200024

>From 6df2af6edbdcf7ac50e356fca6aded37a220a47b Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 8 Jun 2026 19:48:19 +0000
Subject: [PATCH 1/2] first implment of lower scmp

---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 105 +++++++++++++++++++-
 llvm/lib/Target/PowerPC/PPCISelLowering.h   |   1 +
 llvm/test/CodeGen/PowerPC/scmp.ll           |  79 ++++++---------
 3 files changed, 137 insertions(+), 48 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 57ac8965aee7b..04ae6358b3c85 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -595,9 +595,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
   // We cannot sextinreg(i1).  Expand to shifts.
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
 
-  // Custom handling for PowerPC ucmp instruction
+  // Custom handling for PowerPC ucmp and scmp instructions
   setOperationAction(ISD::UCMP, MVT::i32, Custom);
   setOperationAction(ISD::UCMP, MVT::i64, isPPC64 ? Custom : Expand);
+  setOperationAction(ISD::SCMP, MVT::i32, Custom);
+  setOperationAction(ISD::SCMP, MVT::i64, isPPC64 ? Custom : Expand);
 
   // NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intended to support
   // SjLj exception handling but a light-weight setjmp/longjmp replacement to
@@ -12781,6 +12783,87 @@ SDValue PPCTargetLowering::LowerUCMP(SDValue Op, SelectionDAG &DAG) const {
   return DAG.getSExtOrTrunc(ResPair.getValue(0), DL, ResVT);
 }
 
+// Lower signed 3-way compare producing -1/0/1.
+// For PowerPC with SETB (P9+), use the default expansion.
+// For pre-P9, we generate a custom sequence using comparison and bit
+// extraction.
+//   cmpw       cr7, LHS, RHS
+//   mfocrf     r, CR7
+//   rlwinm     LT, r, 29, 31, 31  (extract LT bit from CR7)
+//   rlwinm     GT, r, 30, 31, 31  (extract GT bit from CR7)
+//   subf       result, LT, GT     (GT - LT = -1/0/1)
+SDValue PPCTargetLowering::LowerSCMP(SDValue Op, SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  SDValue LHS = Op.getOperand(0);
+  SDValue RHS = Op.getOperand(1);
+  EVT VT = LHS.getValueType();
+  EVT ResVT = Op.getValueType();
+
+  // For P9+, use the default expansion which will use SETB instruction
+  if (Subtarget.isISA3_0())
+    return SDValue();
+
+  // For pre-P9, generate custom sequence without SETB
+  bool Is64BitCmp = (VT == MVT::i64);
+
+  // On PPC64, always use 64-bit operations to avoid extra sign-extension
+  // Even if result type is i32, it will likely be extended to i64 by calling
+  // convention
+  bool Use64BitOps = Subtarget.isPPC64();
+
+  // Perform comparison
+  unsigned CmpOpc = Is64BitCmp ? PPC::CMPD : PPC::CMPW;
+  SDValue Cmp = SDValue(DAG.getMachineNode(CmpOpc, DL, MVT::i32, LHS, RHS), 0);
+
+  // Move comparison result to CR7 to have known bit positions
+  SDValue CR7Reg = DAG.getRegister(PPC::CR7, MVT::i32);
+  SDValue InGlue; // Null incoming glue
+  SDValue CopyToReg =
+      DAG.getCopyToReg(DAG.getEntryNode(), DL, CR7Reg, Cmp, InGlue);
+  SDValue Glue = CopyToReg.getValue(1);
+
+  // Use MFOCRF to read CR7
+  unsigned MFOCRFOpc = Use64BitOps ? PPC::MFOCRF8 : PPC::MFOCRF;
+  EVT MFVT = Use64BitOps ? MVT::i64 : MVT::i32;
+  SDValue MFOCRF =
+      SDValue(DAG.getMachineNode(MFOCRFOpc, DL, MFVT, CR7Reg, Glue), 0);
+
+  // CR7 bits in the result (after MFOCRF):
+  // Bit 28: LT
+  // Bit 29: GT
+  // Bit 30: EQ
+  // Bit 31: SO
+
+  // Extract LT and GT bits using RLWINM
+  unsigned RLWinmOpc = Use64BitOps ? PPC::RLWINM8 : PPC::RLWINM;
+
+  // Extract LT bit (Bit 28 -> Rotate Left 29 to move to bit 31, then mask)
+  SDValue LTOps[] = {MFOCRF, DAG.getTargetConstant(29, DL, MVT::i32),
+                     DAG.getTargetConstant(31, DL, MVT::i32),
+                     DAG.getTargetConstant(31, DL, MVT::i32)};
+  SDValue LTBit = SDValue(DAG.getMachineNode(RLWinmOpc, DL, MFVT, LTOps), 0);
+
+  // Extract GT bit (Bit 29 -> Rotate Left 30 to move to bit 31, then mask)
+  SDValue GTOps[] = {MFOCRF, DAG.getTargetConstant(30, DL, MVT::i32),
+                     DAG.getTargetConstant(31, DL, MVT::i32),
+                     DAG.getTargetConstant(31, DL, MVT::i32)};
+  SDValue GTBit = SDValue(DAG.getMachineNode(RLWinmOpc, DL, MFVT, GTOps), 0);
+
+  // Compute result: GT - LT
+  // If LT: 0 - 1 = -1
+  // If GT: 1 - 0 = 1
+  // If EQ: 0 - 0 = 0
+  unsigned SubOpc = Use64BitOps ? PPC::SUBF8 : PPC::SUBF;
+  SDValue Result =
+      SDValue(DAG.getMachineNode(SubOpc, DL, MFVT, LTBit, GTBit), 0);
+
+  if (ResVT == MFVT)
+    return Result;
+
+  // Adjust result to match expected type (sign-extend or truncate as needed)
+  return DAG.getSExtOrTrunc(Result, DL, ResVT);
+}
+
 /// LowerOperation - Provide custom lowering hooks for some operations.
 ///
 SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
@@ -12890,6 +12973,8 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
     return LowerADDSUBO_CARRY(Op, DAG);
   case ISD::UCMP:
     return LowerUCMP(Op, DAG);
+  case ISD::SCMP:
+    return LowerSCMP(Op, DAG);
   case ISD::STRICT_LRINT:
   case ISD::STRICT_LLRINT:
   case ISD::STRICT_LROUND:
@@ -17771,10 +17856,26 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
         return N->getOperand(0);
     }
     break;
-  case ISD::SIGN_EXTEND:
+  case ISD::SIGN_EXTEND: {
+    // Optimize: sign_extend(scmp) -> scmp with i64 result (on PPC64)
+    // This eliminates the sign_extend when scmp result is being extended to i64
+    // Pattern: t6: i64 = sign_extend t5:i32
+    //          t5: i32 = scmp t2, t4
+    // Result:  t5: i64 = scmp t2, t4
+    SDValue N0 = N->getOperand(0);
+    if (Subtarget.isPPC64() && N0.getOpcode() == ISD::SCMP &&
+        N->getValueType(0) == MVT::i64 && N0.getValueType() == MVT::i32 &&
+        N0.hasOneUse()) {
+      // Recreate the SCMP with i64 result type directly
+      SDValue LHS = N0.getOperand(0);
+      SDValue RHS = N0.getOperand(1);
+      return DAG.getNode(ISD::SCMP, dl, MVT::i64, LHS, RHS);
+    }
+
     if (SDValue SECC = combineSignExtendSetCC(N, DCI))
       return SECC;
     [[fallthrough]];
+  }
   case ISD::ZERO_EXTEND:
     if (SDValue RetV = combineZextSetccWithZero(N, DCI.DAG))
       return RetV;
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index b7a862ac6d88f..eb77945fa52c0 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -741,6 +741,7 @@ namespace llvm {
     SDValue LowerADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerUCMP(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerSCMP(SDValue Op, SelectionDAG &DAG) const;
     SDValue lowerToLibCall(const char *LibCallName, SDValue Op,
                            SelectionDAG &DAG) const;
     SDValue lowerLibCallBasedOnType(const char *LibCallFloatName,
diff --git a/llvm/test/CodeGen/PowerPC/scmp.ll b/llvm/test/CodeGen/PowerPC/scmp.ll
index 107137c0bea7c..0b823e81c1a5f 100644
--- a/llvm/test/CodeGen/PowerPC/scmp.ll
+++ b/llvm/test/CodeGen/PowerPC/scmp.ll
@@ -4,11 +4,11 @@
 define i8 @scmp_8_8(i8 signext %x, i8 signext %y) nounwind {
 ; CHECK-LABEL: scmp_8_8:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    cmpw 3, 4
-; CHECK-NEXT:    sub 5, 4, 3
-; CHECK-NEXT:    li 3, -1
-; CHECK-NEXT:    rldicl 5, 5, 1, 63
-; CHECK-NEXT:    isellt 3, 3, 5
+; CHECK-NEXT:    cmpw 7, 3, 4
+; CHECK-NEXT:    mfocrf 3, 1
+; CHECK-NEXT:    rlwinm 4, 3, 30, 31, 31
+; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
+; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
   %1 = call i8 @llvm.scmp(i8 %x, i8 %y)
   ret i8 %1
@@ -17,11 +17,11 @@ define i8 @scmp_8_8(i8 signext %x, i8 signext %y) nounwind {
 define i8 @scmp_8_16(i16 signext %x, i16 signext %y) nounwind {
 ; CHECK-LABEL: scmp_8_16:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    cmpw 3, 4
-; CHECK-NEXT:    sub 5, 4, 3
-; CHECK-NEXT:    li 3, -1
-; CHECK-NEXT:    rldicl 5, 5, 1, 63
-; CHECK-NEXT:    isellt 3, 3, 5
+; CHECK-NEXT:    cmpw 7, 3, 4
+; CHECK-NEXT:    mfocrf 3, 1
+; CHECK-NEXT:    rlwinm 4, 3, 30, 31, 31
+; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
+; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
   %1 = call i8 @llvm.scmp(i16 %x, i16 %y)
   ret i8 %1
@@ -30,13 +30,11 @@ define i8 @scmp_8_16(i16 signext %x, i16 signext %y) nounwind {
 define i8 @scmp_8_32(i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: scmp_8_32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    extsw 4, 4
-; CHECK-NEXT:    extsw 3, 3
-; CHECK-NEXT:    cmpw 3, 4
+; CHECK-NEXT:    cmpw 7, 3, 4
+; CHECK-NEXT:    mfocrf 3, 1
+; CHECK-NEXT:    rlwinm 4, 3, 30, 31, 31
+; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
 ; CHECK-NEXT:    sub 3, 4, 3
-; CHECK-NEXT:    li 4, -1
-; CHECK-NEXT:    rldicl 3, 3, 1, 63
-; CHECK-NEXT:    isellt 3, 4, 3
 ; CHECK-NEXT:    blr
   %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
   ret i8 %1
@@ -45,14 +43,11 @@ define i8 @scmp_8_32(i32 %x, i32 %y) nounwind {
 define i8 @scmp_8_64(i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: scmp_8_64:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    sradi 5, 4, 63
-; CHECK-NEXT:    rldicl 6, 3, 1, 63
-; CHECK-NEXT:    subc 7, 4, 3
-; CHECK-NEXT:    adde 5, 6, 5
-; CHECK-NEXT:    cmpd 3, 4
-; CHECK-NEXT:    li 3, -1
-; CHECK-NEXT:    xori 5, 5, 1
-; CHECK-NEXT:    isellt 3, 3, 5
+; CHECK-NEXT:    cmpd 7, 3, 4
+; CHECK-NEXT:    mfocrf 3, 1
+; CHECK-NEXT:    rlwinm 4, 3, 30, 31, 31
+; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
+; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
   %1 = call i8 @llvm.scmp(i64 %x, i64 %y)
   ret i8 %1
@@ -82,13 +77,11 @@ define i8 @scmp_8_128(i128 %x, i128 %y) nounwind {
 define i32 @scmp_32_32(i32 %x, i32 %y) nounwind {
 ; CHECK-LABEL: scmp_32_32:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    extsw 4, 4
-; CHECK-NEXT:    extsw 3, 3
-; CHECK-NEXT:    cmpw 3, 4
+; CHECK-NEXT:    cmpw 7, 3, 4
+; CHECK-NEXT:    mfocrf 3, 1
+; CHECK-NEXT:    rlwinm 4, 3, 30, 31, 31
+; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
 ; CHECK-NEXT:    sub 3, 4, 3
-; CHECK-NEXT:    li 4, -1
-; CHECK-NEXT:    rldicl 3, 3, 1, 63
-; CHECK-NEXT:    isellt 3, 4, 3
 ; CHECK-NEXT:    blr
   %1 = call i32 @llvm.scmp(i32 %x, i32 %y)
   ret i32 %1
@@ -97,14 +90,11 @@ define i32 @scmp_32_32(i32 %x, i32 %y) nounwind {
 define i32 @scmp_32_64(i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: scmp_32_64:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    sradi 5, 4, 63
-; CHECK-NEXT:    rldicl 6, 3, 1, 63
-; CHECK-NEXT:    subc 7, 4, 3
-; CHECK-NEXT:    adde 5, 6, 5
-; CHECK-NEXT:    cmpd 3, 4
-; CHECK-NEXT:    li 3, -1
-; CHECK-NEXT:    xori 5, 5, 1
-; CHECK-NEXT:    isellt 3, 3, 5
+; CHECK-NEXT:    cmpd 7, 3, 4
+; CHECK-NEXT:    mfocrf 3, 1
+; CHECK-NEXT:    rlwinm 4, 3, 30, 31, 31
+; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
+; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
   %1 = call i32 @llvm.scmp(i64 %x, i64 %y)
   ret i32 %1
@@ -113,14 +103,11 @@ define i32 @scmp_32_64(i64 %x, i64 %y) nounwind {
 define i64 @scmp_64_64(i64 %x, i64 %y) nounwind {
 ; CHECK-LABEL: scmp_64_64:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    sradi 5, 4, 63
-; CHECK-NEXT:    rldicl 6, 3, 1, 63
-; CHECK-NEXT:    subc 7, 4, 3
-; CHECK-NEXT:    adde 5, 6, 5
-; CHECK-NEXT:    cmpd 3, 4
-; CHECK-NEXT:    li 3, -1
-; CHECK-NEXT:    xori 5, 5, 1
-; CHECK-NEXT:    isellt 3, 3, 5
+; CHECK-NEXT:    cmpd 7, 3, 4
+; CHECK-NEXT:    mfocrf 3, 1
+; CHECK-NEXT:    rlwinm 4, 3, 30, 31, 31
+; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
+; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
   %1 = call i64 @llvm.scmp(i64 %x, i64 %y)
   ret i64 %1

>From 8db47f1c2ec7721f10d7a5c72a0e87996748f953 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Tue, 9 Jun 2026 15:45:11 +0000
Subject: [PATCH 2/2] add more test scenario

---
 llvm/test/CodeGen/PowerPC/scmp.ll | 211 ++++++++++++++++++++++++++++++
 1 file changed, 211 insertions(+)

diff --git a/llvm/test/CodeGen/PowerPC/scmp.ll b/llvm/test/CodeGen/PowerPC/scmp.ll
index 0b823e81c1a5f..c396e11dad87b 100644
--- a/llvm/test/CodeGen/PowerPC/scmp.ll
+++ b/llvm/test/CodeGen/PowerPC/scmp.ll
@@ -1,5 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc -mtriple=ppc64le-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -mtriple=powerpc-ibm-aix7.2.0.0 %s -o - | FileCheck --check-prefix=AIX32 %s
+; RUN: llc -mtriple=powerpc64-ibm-aix7.2.0.0 %s -o - | FileCheck --check-prefix=AIX64 %s
+
 
 define i8 @scmp_8_8(i8 signext %x, i8 signext %y) nounwind {
 ; CHECK-LABEL: scmp_8_8:
@@ -10,6 +13,24 @@ define i8 @scmp_8_8(i8 signext %x, i8 signext %y) nounwind {
 ; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
 ; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
+;
+; AIX32-LABEL: scmp_8_8:
+; AIX32:       # %bb.0:
+; AIX32-NEXT:    cmpw 7, 3, 4
+; AIX32-NEXT:    mfocrf 3, 1
+; AIX32-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX32-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX32-NEXT:    sub 3, 4, 3
+; AIX32-NEXT:    blr
+;
+; AIX64-LABEL: scmp_8_8:
+; AIX64:       # %bb.0:
+; AIX64-NEXT:    cmpw 7, 3, 4
+; AIX64-NEXT:    mfocrf 3, 1
+; AIX64-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX64-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX64-NEXT:    sub 3, 4, 3
+; AIX64-NEXT:    blr
   %1 = call i8 @llvm.scmp(i8 %x, i8 %y)
   ret i8 %1
 }
@@ -23,6 +44,24 @@ define i8 @scmp_8_16(i16 signext %x, i16 signext %y) nounwind {
 ; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
 ; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
+;
+; AIX32-LABEL: scmp_8_16:
+; AIX32:       # %bb.0:
+; AIX32-NEXT:    cmpw 7, 3, 4
+; AIX32-NEXT:    mfocrf 3, 1
+; AIX32-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX32-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX32-NEXT:    sub 3, 4, 3
+; AIX32-NEXT:    blr
+;
+; AIX64-LABEL: scmp_8_16:
+; AIX64:       # %bb.0:
+; AIX64-NEXT:    cmpw 7, 3, 4
+; AIX64-NEXT:    mfocrf 3, 1
+; AIX64-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX64-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX64-NEXT:    sub 3, 4, 3
+; AIX64-NEXT:    blr
   %1 = call i8 @llvm.scmp(i16 %x, i16 %y)
   ret i8 %1
 }
@@ -36,6 +75,24 @@ define i8 @scmp_8_32(i32 %x, i32 %y) nounwind {
 ; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
 ; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
+;
+; AIX32-LABEL: scmp_8_32:
+; AIX32:       # %bb.0:
+; AIX32-NEXT:    cmpw 7, 3, 4
+; AIX32-NEXT:    mfocrf 3, 1
+; AIX32-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX32-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX32-NEXT:    sub 3, 4, 3
+; AIX32-NEXT:    blr
+;
+; AIX64-LABEL: scmp_8_32:
+; AIX64:       # %bb.0:
+; AIX64-NEXT:    cmpw 7, 3, 4
+; AIX64-NEXT:    mfocrf 3, 1
+; AIX64-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX64-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX64-NEXT:    sub 3, 4, 3
+; AIX64-NEXT:    blr
   %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
   ret i8 %1
 }
@@ -49,6 +106,32 @@ define i8 @scmp_8_64(i64 %x, i64 %y) nounwind {
 ; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
 ; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
+;
+; AIX32-LABEL: scmp_8_64:
+; AIX32:       # %bb.0:
+; AIX32-NEXT:    cmplw 3, 5
+; AIX32-NEXT:    cmpw 1, 3, 5
+; AIX32-NEXT:    li 3, 1
+; AIX32-NEXT:    cmplw 6, 4, 6
+; AIX32-NEXT:    crandc 20, 5, 2
+; AIX32-NEXT:    crand 21, 2, 25
+; AIX32-NEXT:    crand 22, 2, 24
+; AIX32-NEXT:    li 4, -1
+; AIX32-NEXT:    crnor 20, 21, 20
+; AIX32-NEXT:    crandc 21, 4, 2
+; AIX32-NEXT:    isel 3, 0, 3, 20
+; AIX32-NEXT:    cror 20, 22, 21
+; AIX32-NEXT:    isel 3, 4, 3, 20
+; AIX32-NEXT:    blr
+;
+; AIX64-LABEL: scmp_8_64:
+; AIX64:       # %bb.0:
+; AIX64-NEXT:    cmpd 7, 3, 4
+; AIX64-NEXT:    mfocrf 3, 1
+; AIX64-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX64-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX64-NEXT:    sub 3, 4, 3
+; AIX64-NEXT:    blr
   %1 = call i8 @llvm.scmp(i64 %x, i64 %y)
   ret i8 %1
 }
@@ -70,6 +153,62 @@ define i8 @scmp_8_128(i128 %x, i128 %y) nounwind {
 ; CHECK-NEXT:    cror 20, 20, 21
 ; CHECK-NEXT:    isel 3, 4, 3, 20
 ; CHECK-NEXT:    blr
+;
+; AIX32-LABEL: scmp_8_128:
+; AIX32:       # %bb.0:
+; AIX32-NEXT:    cmplw 3, 7
+; AIX32-NEXT:    cmpw 1, 3, 7
+; AIX32-NEXT:    xor 3, 3, 7
+; AIX32-NEXT:    cmplw 6, 4, 8
+; AIX32-NEXT:    mfcr 12
+; AIX32-NEXT:    stw 12, 4(1)
+; AIX32-NEXT:    crandc 20, 5, 2
+; AIX32-NEXT:    crand 21, 2, 25
+; AIX32-NEXT:    xor 4, 4, 8
+; AIX32-NEXT:    cmplw 7, 5, 9
+; AIX32-NEXT:    cmplw 2, 6, 10
+; AIX32-NEXT:    or 3, 4, 3
+; AIX32-NEXT:    lwz 12, 4(1)
+; AIX32-NEXT:    li 4, -1
+; AIX32-NEXT:    cror 25, 21, 20
+; AIX32-NEXT:    cmplwi 5, 3, 0
+; AIX32-NEXT:    crandc 21, 29, 30
+; AIX32-NEXT:    crand 23, 30, 9
+; AIX32-NEXT:    li 3, 1
+; AIX32-NEXT:    cror 21, 23, 21
+; AIX32-NEXT:    crandc 20, 25, 22
+; AIX32-NEXT:    crand 23, 2, 24
+; AIX32-NEXT:    crand 24, 30, 8
+; AIX32-NEXT:    mtocrf 32, 12
+; AIX32-NEXT:    crand 21, 22, 21
+; AIX32-NEXT:    crnor 20, 21, 20
+; AIX32-NEXT:    crandc 21, 4, 2
+; AIX32-NEXT:    cror 21, 23, 21
+; AIX32-NEXT:    crandc 23, 28, 30
+; AIX32-NEXT:    isel 3, 0, 3, 20
+; AIX32-NEXT:    cror 23, 24, 23
+; AIX32-NEXT:    crandc 21, 21, 22
+; AIX32-NEXT:    crand 22, 22, 23
+; AIX32-NEXT:    cror 20, 22, 21
+; AIX32-NEXT:    isel 3, 4, 3, 20
+; AIX32-NEXT:    blr
+;
+; AIX64-LABEL: scmp_8_128:
+; AIX64:       # %bb.0:
+; AIX64-NEXT:    cmpld 3, 5
+; AIX64-NEXT:    cmpd 1, 3, 5
+; AIX64-NEXT:    li 3, 1
+; AIX64-NEXT:    cmpld 6, 4, 6
+; AIX64-NEXT:    crandc 20, 5, 2
+; AIX64-NEXT:    crand 21, 2, 25
+; AIX64-NEXT:    crand 22, 2, 24
+; AIX64-NEXT:    li 4, -1
+; AIX64-NEXT:    crnor 20, 21, 20
+; AIX64-NEXT:    crandc 21, 4, 2
+; AIX64-NEXT:    isel 3, 0, 3, 20
+; AIX64-NEXT:    cror 20, 22, 21
+; AIX64-NEXT:    isel 3, 4, 3, 20
+; AIX64-NEXT:    blr
   %1 = call i8 @llvm.scmp(i128 %x, i128 %y)
   ret i8 %1
 }
@@ -83,6 +222,24 @@ define i32 @scmp_32_32(i32 %x, i32 %y) nounwind {
 ; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
 ; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
+;
+; AIX32-LABEL: scmp_32_32:
+; AIX32:       # %bb.0:
+; AIX32-NEXT:    cmpw 7, 3, 4
+; AIX32-NEXT:    mfocrf 3, 1
+; AIX32-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX32-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX32-NEXT:    sub 3, 4, 3
+; AIX32-NEXT:    blr
+;
+; AIX64-LABEL: scmp_32_32:
+; AIX64:       # %bb.0:
+; AIX64-NEXT:    cmpw 7, 3, 4
+; AIX64-NEXT:    mfocrf 3, 1
+; AIX64-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX64-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX64-NEXT:    sub 3, 4, 3
+; AIX64-NEXT:    blr
   %1 = call i32 @llvm.scmp(i32 %x, i32 %y)
   ret i32 %1
 }
@@ -96,6 +253,32 @@ define i32 @scmp_32_64(i64 %x, i64 %y) nounwind {
 ; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
 ; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
+;
+; AIX32-LABEL: scmp_32_64:
+; AIX32:       # %bb.0:
+; AIX32-NEXT:    cmplw 3, 5
+; AIX32-NEXT:    cmpw 1, 3, 5
+; AIX32-NEXT:    li 3, 1
+; AIX32-NEXT:    cmplw 6, 4, 6
+; AIX32-NEXT:    crandc 20, 5, 2
+; AIX32-NEXT:    crand 21, 2, 25
+; AIX32-NEXT:    crand 22, 2, 24
+; AIX32-NEXT:    li 4, -1
+; AIX32-NEXT:    crnor 20, 21, 20
+; AIX32-NEXT:    crandc 21, 4, 2
+; AIX32-NEXT:    isel 3, 0, 3, 20
+; AIX32-NEXT:    cror 20, 22, 21
+; AIX32-NEXT:    isel 3, 4, 3, 20
+; AIX32-NEXT:    blr
+;
+; AIX64-LABEL: scmp_32_64:
+; AIX64:       # %bb.0:
+; AIX64-NEXT:    cmpd 7, 3, 4
+; AIX64-NEXT:    mfocrf 3, 1
+; AIX64-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX64-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX64-NEXT:    sub 3, 4, 3
+; AIX64-NEXT:    blr
   %1 = call i32 @llvm.scmp(i64 %x, i64 %y)
   ret i32 %1
 }
@@ -109,6 +292,34 @@ define i64 @scmp_64_64(i64 %x, i64 %y) nounwind {
 ; CHECK-NEXT:    rlwinm 3, 3, 29, 31, 31
 ; CHECK-NEXT:    sub 3, 4, 3
 ; CHECK-NEXT:    blr
+;
+; AIX32-LABEL: scmp_64_64:
+; AIX32:       # %bb.0:
+; AIX32-NEXT:    cmplw 3, 5
+; AIX32-NEXT:    cmpw 1, 3, 5
+; AIX32-NEXT:    li 3, 1
+; AIX32-NEXT:    cmplw 6, 4, 6
+; AIX32-NEXT:    crandc 20, 5, 2
+; AIX32-NEXT:    crand 21, 2, 25
+; AIX32-NEXT:    li 5, 0
+; AIX32-NEXT:    li 6, -1
+; AIX32-NEXT:    crnor 20, 21, 20
+; AIX32-NEXT:    crand 21, 2, 24
+; AIX32-NEXT:    isel 3, 0, 3, 20
+; AIX32-NEXT:    crandc 20, 4, 2
+; AIX32-NEXT:    cror 20, 21, 20
+; AIX32-NEXT:    isel 4, 6, 3, 20
+; AIX32-NEXT:    isel 3, 6, 5, 20
+; AIX32-NEXT:    blr
+;
+; AIX64-LABEL: scmp_64_64:
+; AIX64:       # %bb.0:
+; AIX64-NEXT:    cmpd 7, 3, 4
+; AIX64-NEXT:    mfocrf 3, 1
+; AIX64-NEXT:    rlwinm 4, 3, 30, 31, 31
+; AIX64-NEXT:    rlwinm 3, 3, 29, 31, 31
+; AIX64-NEXT:    sub 3, 4, 3
+; AIX64-NEXT:    blr
   %1 = call i64 @llvm.scmp(i64 %x, i64 %y)
   ret i64 %1
 }



More information about the llvm-commits mailing list