[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