forked from OSchip/llvm-project
[SystemZ] Extend 32-bit RISBG optimizations to high words
This involves using RISB[LH]G, whereas the equivalent z10 optimization uses RISBG. llvm-svn: 191770
This commit is contained in:
parent
a484bc00ff
commit
3ad5a15b72
|
@ -266,8 +266,8 @@ class SystemZDAGToDAGISel : public SelectionDAGISel {
|
|||
// Return true on success.
|
||||
bool expandRxSBG(RxSBGOperands &RxSBG) const;
|
||||
|
||||
// Return an undefined i64 value.
|
||||
SDValue getUNDEF64(SDLoc DL) const;
|
||||
// Return an undefined value of type VT.
|
||||
SDValue getUNDEF(SDLoc DL, EVT VT) const;
|
||||
|
||||
// Convert N to VT, if it isn't already.
|
||||
SDValue convertTo(SDLoc DL, EVT VT, SDValue N) const;
|
||||
|
@ -832,15 +832,15 @@ bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
|
|||
}
|
||||
}
|
||||
|
||||
SDValue SystemZDAGToDAGISel::getUNDEF64(SDLoc DL) const {
|
||||
SDNode *N = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64);
|
||||
SDValue SystemZDAGToDAGISel::getUNDEF(SDLoc DL, EVT VT) const {
|
||||
SDNode *N = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT);
|
||||
return SDValue(N, 0);
|
||||
}
|
||||
|
||||
SDValue SystemZDAGToDAGISel::convertTo(SDLoc DL, EVT VT, SDValue N) const {
|
||||
if (N.getValueType() == MVT::i32 && VT == MVT::i64)
|
||||
return CurDAG->getTargetInsertSubreg(SystemZ::subreg_l32,
|
||||
DL, VT, getUNDEF64(DL), N);
|
||||
DL, VT, getUNDEF(DL, MVT::i64), N);
|
||||
if (N.getValueType() == MVT::i64 && VT == MVT::i32)
|
||||
return CurDAG->getTargetExtractSubreg(SystemZ::subreg_l32, DL, VT, N);
|
||||
assert(N.getValueType() == VT && "Unexpected value types");
|
||||
|
@ -880,14 +880,22 @@ SDNode *SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) {
|
|||
}
|
||||
}
|
||||
|
||||
unsigned Opcode = SystemZ::RISBG;
|
||||
EVT OpcodeVT = MVT::i64;
|
||||
if (VT == MVT::i32 && Subtarget.hasHighWord()) {
|
||||
Opcode = SystemZ::RISBMux;
|
||||
OpcodeVT = MVT::i32;
|
||||
RISBG.Start &= 31;
|
||||
RISBG.End &= 31;
|
||||
}
|
||||
SDValue Ops[5] = {
|
||||
getUNDEF64(SDLoc(N)),
|
||||
convertTo(SDLoc(N), MVT::i64, RISBG.Input),
|
||||
getUNDEF(SDLoc(N), OpcodeVT),
|
||||
convertTo(SDLoc(N), OpcodeVT, RISBG.Input),
|
||||
CurDAG->getTargetConstant(RISBG.Start, MVT::i32),
|
||||
CurDAG->getTargetConstant(RISBG.End | 128, MVT::i32),
|
||||
CurDAG->getTargetConstant(RISBG.Rotate, MVT::i32)
|
||||
};
|
||||
N = CurDAG->getMachineNode(SystemZ::RISBG, SDLoc(N), MVT::i64, Ops);
|
||||
N = CurDAG->getMachineNode(Opcode, SDLoc(N), OpcodeVT, Ops);
|
||||
return convertTo(SDLoc(N), VT, SDValue(N, 0)).getNode();
|
||||
}
|
||||
|
||||
|
|
|
@ -500,3 +500,28 @@ define i32 @f23(i32 %old) {
|
|||
"=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4)
|
||||
ret i32 %res2
|
||||
}
|
||||
|
||||
; Test RISB[LH]G insertions involving mixtures of high and low registers.
|
||||
define i32 @f24(i32 %old) {
|
||||
; CHECK-LABEL: f24:
|
||||
; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 1
|
||||
; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 29
|
||||
; CHECK: stepa %r2, [[REG1]], [[REG2]]
|
||||
; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 62
|
||||
; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 37
|
||||
; CHECK: stepb [[REG2]], [[REG3]], %r2
|
||||
; CHECK: br %r14
|
||||
%shift1 = shl i32 %old, 1
|
||||
%and1 = and i32 %shift1, 14
|
||||
%shift2 = lshr i32 %old, 3
|
||||
%and2 = and i32 %shift2, 254
|
||||
%res1 = call i32 asm "stepa $1, $2, $3",
|
||||
"=h,r,r,0"(i32 %old, i32 %and1, i32 %and2)
|
||||
%shift3 = lshr i32 %res1, 2
|
||||
%and3 = and i32 %shift3, 127
|
||||
%shift4 = shl i32 %res1, 5
|
||||
%and4 = and i32 %shift4, 128
|
||||
%res2 = call i32 asm "stepb $1, $2, $3",
|
||||
"=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4)
|
||||
ret i32 %res2
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue