diff options
| author | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2016-11-11 12:43:51 +0000 |
|---|---|---|
| committer | Ulrich Weigand <ulrich.weigand@de.ibm.com> | 2016-11-11 12:43:51 +0000 |
| commit | 5dc7b67c6263fe7f2ced7cb4957e967ab770fab8 (patch) | |
| tree | 04240a86883379ec9f211d43a8de1ab28877dd72 /llvm/lib/Target/SystemZ | |
| parent | 31939e39db2ca3f26868f1f961be0e6c9026a45c (diff) | |
| download | bcm5719-llvm-5dc7b67c6263fe7f2ced7cb4957e967ab770fab8.tar.gz bcm5719-llvm-5dc7b67c6263fe7f2ced7cb4957e967ab770fab8.zip | |
[SystemZ] Use LLGT(R) instructions
This adds support for the 31-to-64-bit zero extension instructions
LLGT and LLGTR and uses them for code generation where appropriate.
Since this operation can also be performed via RISBG, we have to
update SystemZDAGToDAGISel::tryRISBGZero so that we prefer LLGT
over RISBG in case both are possible. The patch includes some
simplification to the tryRISBGZero code; this is not intended
to cause any (further) functional change in codegen.
llvm-svn: 286585
Diffstat (limited to 'llvm/lib/Target/SystemZ')
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 76 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZScheduleZ13.td | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZScheduleZ196.td | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td | 4 |
5 files changed, 50 insertions, 46 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index 154ae474f1d..6d027b899b3 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -935,49 +935,45 @@ bool SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) { Count += 1; if (Count == 0) return false; - if (Count == 1) { - // Prefer to use normal shift instructions over RISBG, since they can handle - // all cases and are sometimes shorter. - if (N->getOpcode() != ISD::AND) - return false; - // Prefer register extensions like LLC over RISBG. Also prefer to start - // out with normal ANDs if one instruction would be enough. We can convert - // these ANDs into an RISBG later if a three-address instruction is useful. - if (VT == MVT::i32 || - RISBG.Mask == 0xff || - RISBG.Mask == 0xffff || - SystemZ::isImmLF(~RISBG.Mask) || - SystemZ::isImmHF(~RISBG.Mask)) { - // Force the new mask into the DAG, since it may include known-one bits. - auto *MaskN = cast<ConstantSDNode>(N->getOperand(1).getNode()); - if (MaskN->getZExtValue() != RISBG.Mask) { - SDValue NewMask = CurDAG->getConstant(RISBG.Mask, DL, VT); - N = CurDAG->UpdateNodeOperands(N, N->getOperand(0), NewMask); - SelectCode(N); - return true; - } - return false; - } - } + // Prefer to use normal shift instructions over RISBG, since they can handle + // all cases and are sometimes shorter. + if (Count == 1 && N->getOpcode() != ISD::AND) + return false; - // If the RISBG operands require no rotation and just masks the bottom - // 8/16 bits, attempt to convert this to a LLC zero extension. - if (RISBG.Rotate == 0 && (RISBG.Mask == 0xff || RISBG.Mask == 0xffff)) { - unsigned OpCode = (RISBG.Mask == 0xff ? SystemZ::LLGCR : SystemZ::LLGHR); - if (VT == MVT::i32) { - if (Subtarget->hasHighWord()) - OpCode = (RISBG.Mask == 0xff ? SystemZ::LLCRMux : SystemZ::LLHRMux); - else - OpCode = (RISBG.Mask == 0xff ? SystemZ::LLCR : SystemZ::LLHR); + // Prefer register extensions like LLC over RISBG. Also prefer to start + // out with normal ANDs if one instruction would be enough. We can convert + // these ANDs into an RISBG later if a three-address instruction is useful. + if (RISBG.Rotate == 0) { + bool PreferAnd = false; + // Prefer AND for any 32-bit and-immediate operation. + if (VT == MVT::i32) + PreferAnd = true; + // As well as for any 64-bit operation that can be implemented via LLC(R), + // LLH(R), LLGT(R), or one of the and-immediate instructions. + else if (RISBG.Mask == 0xff || + RISBG.Mask == 0xffff || + RISBG.Mask == 0x7fffffff || + SystemZ::isImmLF(~RISBG.Mask) || + SystemZ::isImmHF(~RISBG.Mask)) + PreferAnd = true; + if (PreferAnd) { + // Replace the current node with an AND. Note that the current node + // might already be that same AND, in which case it is already CSE'd + // with it, and we must not call ReplaceNode. + SDValue In = convertTo(DL, VT, RISBG.Input); + SDValue Mask = CurDAG->getConstant(RISBG.Mask, DL, VT); + SDValue New = CurDAG->getNode(ISD::AND, DL, VT, In, Mask); + if (N != New.getNode()) { + insertDAGNode(CurDAG, N, Mask); + insertDAGNode(CurDAG, N, New); + ReplaceNode(N, New.getNode()); + N = New.getNode(); + } + // Now, select the machine opcode to implement this operation. + SelectCode(N); + return true; } - - SDValue In = convertTo(DL, VT, RISBG.Input); - SDValue New = convertTo( - DL, VT, SDValue(CurDAG->getMachineNode(OpCode, DL, VT, In), 0)); - ReplaceUses(N, New.getNode()); - CurDAG->RemoveDeadNode(N); - return true; } unsigned Opcode = SystemZ::RISBG; diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td index a80b0d2dd2f..d030ff0cad5 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td @@ -575,6 +575,14 @@ def LLGF : UnaryRXY<"llgf", 0xE316, azextloadi32, GR64, 4>; def LLGHRL : UnaryRILPC<"llghrl", 0xC46, aligned_azextloadi16, GR64>; def LLGFRL : UnaryRILPC<"llgfrl", 0xC4E, aligned_azextloadi32, GR64>; +// 31-to-64-bit zero extensions. +def LLGTR : UnaryRRE<"llgtr", 0xB917, null_frag, GR64, GR64>; +def LLGT : UnaryRXY<"llgt", 0xE317, null_frag, GR64, 4>; +def : Pat<(and GR64:$src, 0x7fffffff), + (LLGTR GR64:$src)>; +def : Pat<(and (i64 (azextloadi32 bdxaddr20only:$src)), 0x7fffffff), + (LLGT bdxaddr20only:$src)>; + //===----------------------------------------------------------------------===// // Truncations //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td index 7bf15b40431..3be98d128ed 100644 --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td @@ -237,12 +237,12 @@ def : InstRW<[FXa, LSU, Lat5], (instregex "LG(H|F)RL$")>; def : InstRW<[FXa], (instregex "LLCR(Mux)?$")>; def : InstRW<[FXa], (instregex "LLHR(Mux)?$")>; -def : InstRW<[FXa], (instregex "LLG(C|H|F)R$")>; +def : InstRW<[FXa], (instregex "LLG(C|H|F|T)R$")>; def : InstRW<[LSU], (instregex "LLC(Mux)?$")>; def : InstRW<[LSU], (instregex "LLH(Mux)?$")>; def : InstRW<[FXa, LSU, Lat5], (instregex "LL(C|H)H$")>; def : InstRW<[LSU], (instregex "LLHRL$")>; -def : InstRW<[LSU], (instregex "LLG(C|H|F|HRL|FRL)$")>; +def : InstRW<[LSU], (instregex "LLG(C|H|F|T|HRL|FRL)$")>; //===----------------------------------------------------------------------===// // Truncations diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td index 06575059328..4f28c519336 100644 --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td @@ -212,12 +212,12 @@ def : InstRW<[FXU, LSU, Lat5], (instregex "LG(H|F)RL$")>; def : InstRW<[FXU], (instregex "LLCR(Mux)?$")>; def : InstRW<[FXU], (instregex "LLHR(Mux)?$")>; -def : InstRW<[FXU], (instregex "LLG(C|F|H)R$")>; +def : InstRW<[FXU], (instregex "LLG(C|F|H|T)R$")>; def : InstRW<[LSU], (instregex "LLC(Mux)?$")>; def : InstRW<[LSU], (instregex "LLH(Mux)?$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "LL(C|H)H$")>; def : InstRW<[LSU], (instregex "LLHRL$")>; -def : InstRW<[LSU], (instregex "LLG(C|F|H|FRL|HRL)$")>; +def : InstRW<[LSU], (instregex "LLG(C|F|H|T|FRL|HRL)$")>; //===----------------------------------------------------------------------===// // Truncations diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td index e302d4606b4..3f3391b843b 100644 --- a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td @@ -214,12 +214,12 @@ def : InstRW<[FXU, LSU, Lat5], (instregex "LG(H|F)RL$")>; def : InstRW<[FXU], (instregex "LLCR(Mux)?$")>; def : InstRW<[FXU], (instregex "LLHR(Mux)?$")>; -def : InstRW<[FXU], (instregex "LLG(C|H|F)R$")>; +def : InstRW<[FXU], (instregex "LLG(C|H|F|T)R$")>; def : InstRW<[LSU], (instregex "LLC(Mux)?$")>; def : InstRW<[LSU], (instregex "LLH(Mux)?$")>; def : InstRW<[FXU, LSU, Lat5], (instregex "LL(C|H)H$")>; def : InstRW<[LSU], (instregex "LLHRL$")>; -def : InstRW<[LSU], (instregex "LLG(C|H|F|HRL|FRL)$")>; +def : InstRW<[LSU], (instregex "LLG(C|H|F|T|HRL|FRL)$")>; //===----------------------------------------------------------------------===// // Truncations |

