[llvm] r273433 - [SystemZ] Recognize RISBG opportunities involving a truncate
Zhan Jun Liau via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 22 09:16:27 PDT 2016
Author: zhanjunl
Date: Wed Jun 22 11:16:27 2016
New Revision: 273433
URL: http://llvm.org/viewvc/llvm-project?rev=273433&view=rev
Log:
[SystemZ] Recognize RISBG opportunities involving a truncate
Summary:
Recognize RISBG opportunities where the end result is narrower than the
original input - where a truncate separates the shift/and operations.
The motivating case is some code in postgres which looks like:
srlg %r2, %r0, 11
nilh %r2, 255
Reviewers: uweigand
Author: RolandF
Differential Revision: http://reviews.llvm.org/D21452
Modified:
llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll
llvm/trunk/test/CodeGen/SystemZ/risbg-02.ll
Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp?rev=273433&r1=273432&r2=273433&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp Wed Jun 22 11:16:27 2016
@@ -113,7 +113,8 @@ static uint64_t allOnes(unsigned int Cou
// (and (rotl Input, Rotate), Mask)
//
// otherwise. The output value has BitSize bits, although Input may be
-// narrower (in which case the upper bits are don't care).
+// narrower (in which case the upper bits are don't care), or wider (in which
+// case the result will be truncated as part of the operation).
struct RxSBGOperands {
RxSBGOperands(unsigned Op, SDValue N)
: Opcode(Op), BitSize(N.getValueType().getSizeInBits()),
@@ -745,6 +746,16 @@ bool SystemZDAGToDAGISel::expandRxSBG(Rx
SDValue N = RxSBG.Input;
unsigned Opcode = N.getOpcode();
switch (Opcode) {
+ case ISD::TRUNCATE: {
+ if (RxSBG.Opcode == SystemZ::RNSBG)
+ return false;
+ uint64_t BitSize = N.getValueType().getSizeInBits();
+ uint64_t Mask = allOnes(BitSize);
+ if (!refineRxSBGMask(RxSBG, Mask))
+ return false;
+ RxSBG.Input = N.getOperand(0);
+ return true;
+ }
case ISD::AND: {
if (RxSBG.Opcode == SystemZ::RNSBG)
return false;
@@ -916,7 +927,11 @@ bool SystemZDAGToDAGISel::tryRISBGZero(S
RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0));
unsigned Count = 0;
while (expandRxSBG(RISBG))
- if (RISBG.Input.getOpcode() != ISD::ANY_EXTEND)
+ // The widening or narrowing is expected to be free.
+ // Counting widening or narrowing as a saved operation will result in
+ // preferring an R*SBG over a simple shift/logical instruction.
+ if (RISBG.Input.getOpcode() != ISD::ANY_EXTEND &&
+ RISBG.Input.getOpcode() != ISD::TRUNCATE)
Count += 1;
if (Count == 0)
return false;
@@ -1004,7 +1019,11 @@ bool SystemZDAGToDAGISel::tryRxSBG(SDNod
unsigned Count[] = { 0, 0 };
for (unsigned I = 0; I < 2; ++I)
while (expandRxSBG(RxSBG[I]))
- if (RxSBG[I].Input.getOpcode() != ISD::ANY_EXTEND)
+ // The widening or narrowing is expected to be free.
+ // Counting widening or narrowing as a saved operation will result in
+ // preferring an R*SBG over a simple shift/logical instruction.
+ if (RxSBG[I].Input.getOpcode() != ISD::ANY_EXTEND &&
+ RxSBG[I].Input.getOpcode() != ISD::TRUNCATE)
Count[I] += 1;
// Do nothing if neither operand is suitable.
Modified: llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll?rev=273433&r1=273432&r2=273433&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/risbg-01.ll Wed Jun 22 11:16:27 2016
@@ -480,3 +480,24 @@ define i64 @f42(i1 %x) {
%ext2 = zext i8 %ext to i64
ret i64 %ext2
}
+
+; Check that we get the case where a 64-bit shift is used by a 32-bit and.
+define signext i32 @f43(i64 %x) {
+; CHECK-LABEL: f43:
+; CHECK: risbg [[REG:%r[0-5]]], %r2, 32, 189, 52
+; CHECK: lgfr %r2, [[REG]]
+ %shr3 = lshr i64 %x, 12
+ %shr3.tr = trunc i64 %shr3 to i32
+ %conv = and i32 %shr3.tr, -4
+ ret i32 %conv
+}
+
+; Check that we don't get the case where the 32-bit and mask is not contiguous
+define signext i32 @f44(i64 %x) {
+; CHECK-LABEL: f44:
+; CHECK: srlg [[REG:%r[0-5]]], %r2, 12
+ %shr4 = lshr i64 %x, 12
+ %conv = trunc i64 %shr4 to i32
+ %and = and i32 %conv, 10
+ ret i32 %and
+}
Modified: llvm/trunk/test/CodeGen/SystemZ/risbg-02.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/risbg-02.ll?rev=273433&r1=273432&r2=273433&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/risbg-02.ll (original)
+++ llvm/trunk/test/CodeGen/SystemZ/risbg-02.ll Wed Jun 22 11:16:27 2016
@@ -91,3 +91,28 @@ define i64 @f8(i64 %a, i64 %b) {
%or = or i64 %anda, %shrb
ret i64 %or
}
+
+; Check that we can get the case where a 64-bit shift feeds a 32-bit or of
+; ands with complement masks.
+define signext i32 @f9(i64 %x, i32 signext %y) {
+; CHECK-LABEL: f9:
+; CHECK: risbg [[REG:%r[0-5]]], %r2, 48, 63, 16
+; CHECK: lgfr %r2, [[REG]]
+ %shr6 = lshr i64 %x, 48
+ %conv = trunc i64 %shr6 to i32
+ %and1 = and i32 %y, -65536
+ %or = or i32 %conv, %and1
+ ret i32 %or
+}
+
+; Check that we don't get the case where a 64-bit shift feeds a 32-bit or of
+; ands with incompatible masks.
+define signext i32 @f10(i64 %x, i32 signext %y) {
+; CHECK-LABEL: f10:
+; CHECK: nilf %r3, 4278190080
+ %shr6 = lshr i64 %x, 48
+ %conv = trunc i64 %shr6 to i32
+ %and1 = and i32 %y, -16777216
+ %or = or i32 %conv, %and1
+ ret i32 %or
+}
More information about the llvm-commits
mailing list