diff options
| author | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2017-09-23 04:41:34 +0000 |
|---|---|---|
| committer | Nemanja Ivanovic <nemanja.i.ibm@gmail.com> | 2017-09-23 04:41:34 +0000 |
| commit | 41c4a109d893604fe2570598ee62fceff6e1aee8 (patch) | |
| tree | 63fcc2e2836519f888c733c0de507bb062585d91 | |
| parent | cdb06f2150d0c75bf7ff13971fd40075568c0226 (diff) | |
| download | bcm5719-llvm-41c4a109d893604fe2570598ee62fceff6e1aee8.tar.gz bcm5719-llvm-41c4a109d893604fe2570598ee62fceff6e1aee8.zip | |
[PowerPC] Eliminate compares - add i32 sext/zext handling for SETLT/SETGT
As mentioned in https://reviews.llvm.org/D33718, this simply adds another
pattern to the compare elimination sequence and is committed without a
differential revision.
llvm-svn: 314055
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 101 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll | 7 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/no-pref-jumps.ll | 10 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/testComparesigtsc.ll | 116 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/testComparesigtsi.ll | 116 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/testComparesigtss.ll | 117 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/testComparesiltsc.ll | 83 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/testComparesiltsi.ll | 85 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/testComparesiltss.ll | 83 |
9 files changed, 711 insertions, 7 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index dbe4269f004..d76ef72a28d 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -2870,6 +2870,8 @@ SDValue PPCDAGToDAGISel::get32BitZExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC, int64_t RHSValue, SDLoc dl) { bool IsRHSZero = RHSValue == 0; + bool IsRHSOne = RHSValue == 1; + bool IsRHSNegOne = RHSValue == -1LL; switch (CC) { default: return SDValue(); case ISD::SETEQ: { @@ -2903,6 +2905,9 @@ SDValue PPCDAGToDAGISel::get32BitZExtCompare(SDValue LHS, SDValue RHS, // (zext (setcc %a, 0, setge)) -> (lshr (~ %a), 31) if(IsRHSZero) return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt); + + // Not a special case (i.e. RHS == 0). Handle (%a >= %b) as (%b <= %a) + // by swapping inputs and falling through. std::swap(LHS, RHS); ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); IsRHSZero = RHSConst && RHSConst->isNullValue(); @@ -2926,6 +2931,55 @@ SDValue PPCDAGToDAGISel::get32BitZExtCompare(SDValue LHS, SDValue RHS, SDValue(CurDAG->getMachineNode(PPC::XORI8, dl, MVT::i64, Shift, getI32Imm(1, dl)), 0); } + case ISD::SETGT: { + // (zext (setcc %a, %b, setgt)) -> (lshr (sub %b, %a), 63) + // (zext (setcc %a, -1, setgt)) -> (lshr (~ %a), 31) + // (zext (setcc %a, 0, setgt)) -> (lshr (- %a), 63) + // Handle SETLT -1 (which is equivalent to SETGE 0). + if (IsRHSNegOne) + return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt); + + if (IsRHSZero) { + // The upper 32-bits of the register can't be undefined for this sequence. + LHS = signExtendInputIfNeeded(LHS); + RHS = signExtendInputIfNeeded(RHS); + SDValue Neg = + SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, LHS), 0); + return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, + Neg, getI32Imm(1, dl), getI32Imm(63, dl)), 0); + } + // Not a special case (i.e. RHS == 0 or RHS == -1). Handle (%a > %b) as + // (%b < %a) by swapping inputs and falling through. + std::swap(LHS, RHS); + ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); + IsRHSZero = RHSConst && RHSConst->isNullValue(); + IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1; + LLVM_FALLTHROUGH; + } + case ISD::SETLT: { + // (zext (setcc %a, %b, setlt)) -> (lshr (sub %a, %b), 63) + // (zext (setcc %a, 1, setlt)) -> (xor (lshr (- %a), 63), 1) + // (zext (setcc %a, 0, setlt)) -> (lshr %a, 31) + // Handle SETLT 1 (which is equivalent to SETLE 0). + if (IsRHSOne) + return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt); + + if (IsRHSZero) { + SDValue ShiftOps[] = { LHS, getI32Imm(1, dl), getI32Imm(31, dl), + getI32Imm(31, dl) }; + return SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, + ShiftOps), 0); + } + + // The upper 32-bits of the register can't be undefined for this sequence. + LHS = signExtendInputIfNeeded(LHS); + RHS = signExtendInputIfNeeded(RHS); + SDValue SUBFNode = + SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0); + return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, + SUBFNode, getI64Imm(1, dl), + getI64Imm(63, dl)), 0); + } } } @@ -2935,6 +2989,9 @@ SDValue PPCDAGToDAGISel::get32BitSExtCompare(SDValue LHS, SDValue RHS, ISD::CondCode CC, int64_t RHSValue, SDLoc dl) { bool IsRHSZero = RHSValue == 0; + bool IsRHSOne = RHSValue == 1; + bool IsRHSNegOne = RHSValue == -1LL; + switch (CC) { default: return SDValue(); case ISD::SETEQ: { @@ -2978,6 +3035,9 @@ SDValue PPCDAGToDAGISel::get32BitSExtCompare(SDValue LHS, SDValue RHS, // (sext (setcc %a, 0, setge)) -> (ashr (~ %a), 31) if (IsRHSZero) return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt); + + // Not a special case (i.e. RHS == 0). Handle (%a >= %b) as (%b <= %a) + // by swapping inputs and falling through. std::swap(LHS, RHS); ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); IsRHSZero = RHSConst && RHSConst->isNullValue(); @@ -3002,6 +3062,47 @@ SDValue PPCDAGToDAGISel::get32BitSExtCompare(SDValue LHS, SDValue RHS, return SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, Srdi, getI32Imm(-1, dl)), 0); } + case ISD::SETGT: { + // (sext (setcc %a, %b, setgt)) -> (ashr (sub %b, %a), 63) + // (sext (setcc %a, -1, setgt)) -> (ashr (~ %a), 31) + // (sext (setcc %a, 0, setgt)) -> (ashr (- %a), 63) + if (IsRHSNegOne) + return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt); + if (IsRHSZero) { + // The upper 32-bits of the register can't be undefined for this sequence. + LHS = signExtendInputIfNeeded(LHS); + RHS = signExtendInputIfNeeded(RHS); + SDValue Neg = + SDValue(CurDAG->getMachineNode(PPC::NEG8, dl, MVT::i64, LHS), 0); + return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, Neg, + getI64Imm(63, dl)), 0); + } + // Not a special case (i.e. RHS == 0 or RHS == -1). Handle (%a > %b) as + // (%b < %a) by swapping inputs and falling through. + std::swap(LHS, RHS); + ConstantSDNode *RHSConst = dyn_cast<ConstantSDNode>(RHS); + IsRHSZero = RHSConst && RHSConst->isNullValue(); + IsRHSOne = RHSConst && RHSConst->getSExtValue() == 1; + LLVM_FALLTHROUGH; + } + case ISD::SETLT: { + // (sext (setcc %a, %b, setgt)) -> (ashr (sub %a, %b), 63) + // (sext (setcc %a, 1, setgt)) -> (add (lshr (- %a), 63), -1) + // (sext (setcc %a, 0, setgt)) -> (ashr %a, 31) + if (IsRHSOne) + return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt); + if (IsRHSZero) + return SDValue(CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, LHS, + getI32Imm(31, dl)), 0); + + // The upper 32-bits of the register can't be undefined for this sequence. + LHS = signExtendInputIfNeeded(LHS); + RHS = signExtendInputIfNeeded(RHS); + SDValue SUBFNode = + SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl, MVT::i64, RHS, LHS), 0); + return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, + SUBFNode, getI64Imm(63, dl)), 0); + } } } diff --git a/llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll b/llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll index 059665adc35..c8c5108673d 100644 --- a/llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll +++ b/llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll @@ -115,10 +115,9 @@ define signext i32 @zeroEqualityTest04() { ; CHECK-NEXT: li 12, -1 ; CHECK-NEXT: isel 5, 12, 11, 0 ; CHECK-NEXT: .LBB3_3: # %endblock -; CHECK-NEXT: cmpwi 5, 1 -; CHECK-NEXT: li 3, 0 -; CHECK-NEXT: li 4, 1 -; CHECK-NEXT: isel 3, 4, 3, 0 +; CHECK-NEXT: neg 3, 5 +; CHECK-NEXT: rldicl 3, 3, 1, 63 +; CHECK-NEXT: xori 3, 3, 1 ; CHECK-NEXT: blr %call = tail call signext i32 @memcmp(i8* bitcast ([4 x i32]* @zeroEqualityTest02.buffer1 to i8*), i8* bitcast ([4 x i32]* @zeroEqualityTest02.buffer2 to i8*), i64 16) %not.cmp = icmp slt i32 %call, 1 diff --git a/llvm/test/CodeGen/PowerPC/no-pref-jumps.ll b/llvm/test/CodeGen/PowerPC/no-pref-jumps.ll index 71f79409820..44643df09bd 100644 --- a/llvm/test/CodeGen/PowerPC/no-pref-jumps.ll +++ b/llvm/test/CodeGen/PowerPC/no-pref-jumps.ll @@ -11,9 +11,13 @@ entry: br i1 %or.cond, label %if.then, label %if.else ; CHECK-LABEL: @foo -; CHECK: cmpwi -; CHECK: cmpwi -; CHECK: cror +; CHECK: li +; CHECK: li +; CHECK: sub +; CHECK: sub +; CHECK: rldicl +; CHECK: rldicl +; CHECK: or. ; CHECK: blr if.then: ; preds = %entry diff --git a/llvm/test/CodeGen/PowerPC/testComparesigtsc.ll b/llvm/test/CodeGen/PowerPC/testComparesigtsc.ll new file mode 100644 index 00000000000..27692e0f541 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/testComparesigtsc.ll @@ -0,0 +1,116 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl + +@glob = common local_unnamed_addr global i8 0, align 1 + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtsc(i8 signext %a, i8 signext %b) { +; CHECK-LABEL: test_igtsc: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r4, r3 +; CHECK-NEXT: rldicl r3, [[REG]], 1, 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i8 %a, %b + %conv2 = zext i1 %cmp to i32 + ret i32 %conv2 +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtsc_sext(i8 signext %a, i8 signext %b) { +; CHECK-LABEL: test_igtsc_sext: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r4, r3 +; CHECK-NEXT: sradi r3, [[REG]], 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i8 %a, %b + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; FIXME +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtsc_z(i8 signext %a) { +; CHECK-LABEL: test_igtsc_z: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: neg r3, r3 +; CHECK-NEXT: rldicl r3, r3, 1, 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i8 %a, 0 + %conv1 = zext i1 %cmp to i32 + ret i32 %conv1 +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtsc_sext_z(i8 signext %a) { +; CHECK-LABEL: test_igtsc_sext_z: +; CHECK: neg [[REG2:r[0-9]+]], r3 +; CHECK-NEXT: sradi r3, [[REG2]], 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i8 %a, 0 + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind +define void @test_igtsc_store(i8 signext %a, i8 signext %b) { +; CHECK-LABEL: test_igtsc_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r4, r3 +; CHECK: rldicl {{r[0-9]+}}, [[REG]], 1, 63 +entry: + %cmp = icmp sgt i8 %a, %b + %conv3 = zext i1 %cmp to i8 + store i8 %conv3, i8* @glob, align 1 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_igtsc_sext_store(i8 signext %a, i8 signext %b) { +; CHECK-LABEL: test_igtsc_sext_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r4, r3 +; CHECK: sradi {{r[0-9]+}}, [[REG]], 63 +entry: + %cmp = icmp sgt i8 %a, %b + %conv3 = sext i1 %cmp to i8 + store i8 %conv3, i8* @glob, align 1 + ret void +} + +; FIXME +; Function Attrs: norecurse nounwind +define void @test_igtsc_z_store(i8 signext %a) { +; CHECK-LABEL: test_igtsc_z_store: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: addis r4, r2, .LC0@toc@ha +; CHECK-NEXT: neg r3, r3 +; CHECK-NEXT: ld r4, .LC0@toc@l(r4) +; CHECK-NEXT: rldicl r3, r3, 1, 63 +; CHECK-NEXT: stb r3, 0(r4) +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i8 %a, 0 + %conv2 = zext i1 %cmp to i8 + store i8 %conv2, i8* @glob, align 1 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_igtsc_sext_z_store(i8 signext %a) { +; CHECK-LABEL: test_igtsc_sext_z_store: +; CHECK: neg [[REG2:r[0-9]+]], r3 +; CHECK: sradi {{r[0-9]+}}, [[REG2]], 63 +entry: + %cmp = icmp sgt i8 %a, 0 + %conv2 = sext i1 %cmp to i8 + store i8 %conv2, i8* @glob, align 1 + ret void +} diff --git a/llvm/test/CodeGen/PowerPC/testComparesigtsi.ll b/llvm/test/CodeGen/PowerPC/testComparesigtsi.ll new file mode 100644 index 00000000000..a6eda86e5fc --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/testComparesigtsi.ll @@ -0,0 +1,116 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl + +@glob = common local_unnamed_addr global i32 0, align 4 + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtsi(i32 signext %a, i32 signext %b) { +; CHECK-LABEL: test_igtsi: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r4, r3 +; CHECK-NEXT: rldicl r3, [[REG]], 1, 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i32 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtsi_sext(i32 signext %a, i32 signext %b) { +; CHECK-LABEL: test_igtsi_sext: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r4, r3 +; CHECK-NEXT: sradi r3, [[REG]], 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i32 %a, %b + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; FIXME +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtsi_z(i32 signext %a) { +; CHECK-LABEL: test_igtsi_z: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: neg r3, r3 +; CHECK-NEXT: rldicl r3, r3, 1, 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i32 %a, 0 + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtsi_sext_z(i32 signext %a) { +; CHECK-LABEL: test_igtsi_sext_z: +; CHECK: neg [[REG2:r[0-9]+]], r3 +; CHECK-NEXT: sradi r3, [[REG2]], 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i32 %a, 0 + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind +define void @test_igtsi_store(i32 signext %a, i32 signext %b) { +; CHECK-LABEL: test_igtsi_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r4, r3 +; CHECK: rldicl {{r[0-9]+}}, [[REG]], 1, 63 +entry: + %cmp = icmp sgt i32 %a, %b + %conv = zext i1 %cmp to i32 + store i32 %conv, i32* @glob, align 4 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_igtsi_sext_store(i32 signext %a, i32 signext %b) { +; CHECK-LABEL: test_igtsi_sext_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r4, r3 +; CHECK: sradi {{r[0-9]+}}, [[REG]], 63 +entry: + %cmp = icmp sgt i32 %a, %b + %sub = sext i1 %cmp to i32 + store i32 %sub, i32* @glob, align 4 + ret void +} + +; FIXME +; Function Attrs: norecurse nounwind +define void @test_igtsi_z_store(i32 signext %a) { +; CHECK-LABEL: test_igtsi_z_store: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: addis r4, r2, .LC0@toc@ha +; CHECK-NEXT: neg r3, r3 +; CHECK-NEXT: ld r4, .LC0@toc@l(r4) +; CHECK-NEXT: rldicl r3, r3, 1, 63 +; CHECK-NEXT: stw r3, 0(r4) +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i32 %a, 0 + %conv = zext i1 %cmp to i32 + store i32 %conv, i32* @glob, align 4 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_igtsi_sext_z_store(i32 signext %a) { +; CHECK-LABEL: test_igtsi_sext_z_store: +; CHECK: neg [[REG:r[0-9]+]], r3 +; CHECK: sradi {{r[0-9]+}}, [[REG]], 63 +entry: + %cmp = icmp sgt i32 %a, 0 + %sub = sext i1 %cmp to i32 + store i32 %sub, i32* @glob, align 4 + ret void +} diff --git a/llvm/test/CodeGen/PowerPC/testComparesigtss.ll b/llvm/test/CodeGen/PowerPC/testComparesigtss.ll new file mode 100644 index 00000000000..a79d4887229 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/testComparesigtss.ll @@ -0,0 +1,117 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl + +@glob = common local_unnamed_addr global i16 0, align 2 + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtss(i16 signext %a, i16 signext %b) { +; CHECK-LABEL: test_igtss: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG1:r[0-9]+]], r4, r3 +; CHECK-NEXT: rldicl r3, [[REG1]], 1, 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i16 %a, %b + %conv2 = zext i1 %cmp to i32 + ret i32 %conv2 +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtss_sext(i16 signext %a, i16 signext %b) { +; CHECK-LABEL: test_igtss_sext: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r4, r3 +; CHECK-NEXT: sradi r3, [[REG]], 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i16 %a, %b + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; FIXME +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtss_z(i16 signext %a) { +; CHECK-LABEL: test_igtss_z: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: neg r3, r3 +; CHECK-NEXT: rldicl r3, r3, 1, 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i16 %a, 0 + %conv1 = zext i1 %cmp to i32 + ret i32 %conv1 +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_igtss_sext_z(i16 signext %a) { +; CHECK-LABEL: test_igtss_sext_z: +; CHECK: # BB#0: # %entry +; CHECK: neg [[REG2:r[0-9]+]], r3 +; CHECK-NEXT: sradi r3, [[REG2]], 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i16 %a, 0 + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind +define void @test_igtss_store(i16 signext %a, i16 signext %b) { +; CHECK-LABEL: test_igtss_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG1:r[0-9]+]], r4, r3 +; CHECK: rldicl {{r[0-9]+}}, [[REG1]], 1, 63 +entry: + %cmp = icmp sgt i16 %a, %b + %conv3 = zext i1 %cmp to i16 + store i16 %conv3, i16* @glob, align 2 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_igtss_sext_store(i16 signext %a, i16 signext %b) { +; CHECK-LABEL: test_igtss_sext_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r4, r3 +; CHECK: sradi {{r[0-9]+}}, [[REG]], 63 +entry: + %cmp = icmp sgt i16 %a, %b + %conv3 = sext i1 %cmp to i16 + store i16 %conv3, i16* @glob, align 2 + ret void +} + +; FIXME +; Function Attrs: norecurse nounwind +define void @test_igtss_z_store(i16 signext %a) { +; CHECK-LABEL: test_igtss_z_store: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: addis r4, r2, .LC0@toc@ha +; CHECK-NEXT: neg r3, r3 +; CHECK-NEXT: ld r4, .LC0@toc@l(r4) +; CHECK-NEXT: rldicl r3, r3, 1, 63 +; CHECK-NEXT: sth r3, 0(r4) +; CHECK-NEXT: blr +entry: + %cmp = icmp sgt i16 %a, 0 + %conv2 = zext i1 %cmp to i16 + store i16 %conv2, i16* @glob, align 2 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_igtss_sext_z_store(i16 signext %a) { +; CHECK-LABEL: test_igtss_sext_z_store: +; CHECK: neg [[REG2:r[0-9]+]], r3 +; CHECK: sradi {{r[0-9]+}}, [[REG2]], 63 +entry: + %cmp = icmp sgt i16 %a, 0 + %conv2 = sext i1 %cmp to i16 + store i16 %conv2, i16* @glob, align 2 + ret void +} diff --git a/llvm/test/CodeGen/PowerPC/testComparesiltsc.ll b/llvm/test/CodeGen/PowerPC/testComparesiltsc.ll new file mode 100644 index 00000000000..54e278d4321 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/testComparesiltsc.ll @@ -0,0 +1,83 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +@glob = common local_unnamed_addr global i8 0, align 1 + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_iltsc(i8 signext %a, i8 signext %b) { +; CHECK-LABEL: test_iltsc: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r3, r4 +; CHECK-NEXT: rldicl r3, [[REG]], 1, 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp slt i8 %a, %b + %conv2 = zext i1 %cmp to i32 + ret i32 %conv2 +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_iltsc_sext(i8 signext %a, i8 signext %b) { +; CHECK-LABEL: test_iltsc_sext: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r3, r4 +; CHECK-NEXT: sradi r3, [[REG]], 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp slt i8 %a, %b + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_iltsc_sext_z(i8 signext %a) { +; CHECK-LABEL: test_iltsc_sext_z: +; CHECK: srawi r3, r3, 31 +; CHECK-NEXT: blr +entry: + %cmp = icmp slt i8 %a, 0 + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind +define void @test_iltsc_store(i8 signext %a, i8 signext %b) { +; CHECK-LABEL: test_iltsc_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r3, r4 +; CHECK: rldicl {{r[0-9]+}}, [[REG]], 1, 63 +entry: + %cmp = icmp slt i8 %a, %b + %conv3 = zext i1 %cmp to i8 + store i8 %conv3, i8* @glob, align 1 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_iltsc_sext_store(i8 signext %a, i8 signext %b) { +; CHECK-LABEL: test_iltsc_sext_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r3, r4 +; CHECK: sradi {{r[0-9]+}}, [[REG]], 63 +entry: + %cmp = icmp slt i8 %a, %b + %conv3 = sext i1 %cmp to i8 + store i8 %conv3, i8* @glob, align 1 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_iltsc_sext_z_store(i8 signext %a) { +; CHECK-LABEL: test_iltsc_sext_z_store: +; CHECK: srwi {{r[0-9]+}}, r3, 7 +entry: + %cmp = icmp slt i8 %a, 0 + %conv2 = sext i1 %cmp to i8 + store i8 %conv2, i8* @glob, align 1 + ret void +} diff --git a/llvm/test/CodeGen/PowerPC/testComparesiltsi.ll b/llvm/test/CodeGen/PowerPC/testComparesiltsi.ll new file mode 100644 index 00000000000..8a5cdd86921 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/testComparesiltsi.ll @@ -0,0 +1,85 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +@glob = common local_unnamed_addr global i32 0, align 4 + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_iltsi(i32 signext %a, i32 signext %b) { +; CHECK-LABEL: test_iltsi: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r3, r4 +; CHECK-NEXT: rldicl r3, [[REG]], 1, 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp slt i32 %a, %b + %conv = zext i1 %cmp to i32 + ret i32 %conv +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_iltsi_sext(i32 signext %a, i32 signext %b) { +; CHECK-LABEL: test_iltsi_sext: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r3, r4 +; CHECK-NEXT: sradi r3, [[REG]], 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp slt i32 %a, %b + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_iltsi_sext_z(i32 signext %a) { +; CHECK-LABEL: test_iltsi_sext_z: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: srawi r3, r3, 31 +; CHECK-NEXT: blr +entry: + %cmp = icmp slt i32 %a, 0 + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind +define void @test_iltsi_store(i32 signext %a, i32 signext %b) { +; CHECK-LABEL: test_iltsi_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r3, r4 +; CHECK: rldicl {{r[0-9]+}}, [[REG]], 1, 63 +entry: + %cmp = icmp slt i32 %a, %b + %conv = zext i1 %cmp to i32 + store i32 %conv, i32* @glob, align 4 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_iltsi_sext_store(i32 signext %a, i32 signext %b) { +; CHECK-LABEL: test_iltsi_sext_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r3, r4 +; CHECK: sradi {{r[0-9]+}}, [[REG]], 63 +entry: + %cmp = icmp slt i32 %a, %b + %sub = sext i1 %cmp to i32 + store i32 %sub, i32* @glob, align 4 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_iltsi_sext_z_store(i32 signext %a) { +; CHECK-LABEL: test_iltsi_sext_z_store: +; CHECK: srawi {{r[0-9]+}}, r3, 31 +; CHECK: blr +entry: + %cmp = icmp slt i32 %a, 0 + %sub = sext i1 %cmp to i32 + store i32 %sub, i32* @glob, align 4 + ret void +} diff --git a/llvm/test/CodeGen/PowerPC/testComparesiltss.ll b/llvm/test/CodeGen/PowerPC/testComparesiltss.ll new file mode 100644 index 00000000000..a3ec96dda11 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/testComparesiltss.ll @@ -0,0 +1,83 @@ +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -O2 \ +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | FileCheck %s \ +; RUN: --implicit-check-not cmpw --implicit-check-not cmpd --implicit-check-not cmpl +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +@glob = common local_unnamed_addr global i16 0, align 2 + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_iltss(i16 signext %a, i16 signext %b) { +; CHECK-LABEL: test_iltss: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r3, r4 +; CHECK-NEXT: rldicl r3, [[REG]], 1, 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp slt i16 %a, %b + %conv2 = zext i1 %cmp to i32 + ret i32 %conv2 +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_iltss_sext(i16 signext %a, i16 signext %b) { +; CHECK-LABEL: test_iltss_sext: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: sub [[REG:r[0-9]+]], r3, r4 +; CHECK-NEXT: sradi r3, [[REG]], 63 +; CHECK-NEXT: blr +entry: + %cmp = icmp slt i16 %a, %b + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind readnone +define signext i32 @test_iltss_sext_z(i16 signext %a) { +; CHECK-LABEL: test_iltss_sext_z: +; CHECK: srawi r3, r3, 31 +; CHECK-NEXT: blr +entry: + %cmp = icmp slt i16 %a, 0 + %sub = sext i1 %cmp to i32 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind +define void @test_iltss_store(i16 signext %a, i16 signext %b) { +; CHECK-LABEL: test_iltss_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r3, r4 +; CHECK: rldicl {{r[0-9]+}}, [[REG]], 1, 63 +entry: + %cmp = icmp slt i16 %a, %b + %conv3 = zext i1 %cmp to i16 + store i16 %conv3, i16* @glob, align 2 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_iltss_sext_store(i16 signext %a, i16 signext %b) { +; CHECK-LABEL: test_iltss_sext_store: +; CHECK: # BB#0: # %entry +; CHECK: sub [[REG:r[0-9]+]], r3, r4 +; CHECK: sradi {{r[0-9]+}}, [[REG]], 63 +entry: + %cmp = icmp slt i16 %a, %b + %conv3 = sext i1 %cmp to i16 + store i16 %conv3, i16* @glob, align 2 + ret void +} + +; Function Attrs: norecurse nounwind +define void @test_iltss_sext_z_store(i16 signext %a) { +; CHECK-LABEL: test_iltss_sext_z_store: +; CHECK: srwi {{r[0-9]+}}, r3, 15 +entry: + %cmp = icmp slt i16 %a, 0 + %sub = sext i1 %cmp to i16 + store i16 %sub, i16* @glob, align 2 + ret void +} |

