forked from OSchip/llvm-project
Expand 64-bit shifts more optimally if we know that the high bit of the
shift amount is one or zero. For example, for: long long foo1(long long X, int C) { return X << (C|32); } long long foo2(long long X, int C) { return X << (C&~32); } we get: _foo1: movb $31, %cl movl 4(%esp), %edx andb 12(%esp), %cl shll %cl, %edx xorl %eax, %eax ret _foo2: movb $223, %cl movl 4(%esp), %eax movl 8(%esp), %edx andb 12(%esp), %cl shldl %cl, %eax, %edx shll %cl, %eax ret instead of: _foo1: subl $4, %esp movl %ebx, (%esp) movb $32, %bl movl 8(%esp), %eax movl 12(%esp), %edx movb %bl, %cl orb 16(%esp), %cl shldl %cl, %eax, %edx shll %cl, %eax xorl %ecx, %ecx testb %bl, %bl cmovne %eax, %edx cmovne %ecx, %eax movl (%esp), %ebx addl $4, %esp ret _foo2: subl $4, %esp movl %ebx, (%esp) movb $223, %cl movl 8(%esp), %eax movl 12(%esp), %edx andb 16(%esp), %cl shldl %cl, %eax, %edx shll %cl, %eax xorl %ecx, %ecx xorb %bl, %bl testb %bl, %bl cmovne %eax, %edx cmovne %ecx, %eax movl (%esp), %ebx addl $4, %esp ret llvm-svn: 30506
This commit is contained in:
parent
cd3f6ff0e5
commit
875ea0cdbd
|
@ -3781,6 +3781,72 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDOperand Op,SDOperand Amt,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Okay, the shift amount isn't constant. However, if we can tell that it is
|
||||||
|
// >= 32 or < 32, we can still simplify it, without knowing the actual value.
|
||||||
|
uint64_t Mask = NVTBits, KnownZero, KnownOne;
|
||||||
|
TLI.ComputeMaskedBits(Amt, Mask, KnownZero, KnownOne);
|
||||||
|
|
||||||
|
// If we know that the high bit of the shift amount is one, then we can do
|
||||||
|
// this as a couple of simple shifts.
|
||||||
|
if (KnownOne & Mask) {
|
||||||
|
// Mask out the high bit, which we know is set.
|
||||||
|
Amt = DAG.getNode(ISD::AND, Amt.getValueType(), Amt,
|
||||||
|
DAG.getConstant(NVTBits-1, Amt.getValueType()));
|
||||||
|
|
||||||
|
// Expand the incoming operand to be shifted, so that we have its parts
|
||||||
|
SDOperand InL, InH;
|
||||||
|
ExpandOp(Op, InL, InH);
|
||||||
|
switch(Opc) {
|
||||||
|
case ISD::SHL:
|
||||||
|
Lo = DAG.getConstant(0, NVT); // Low part is zero.
|
||||||
|
Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part.
|
||||||
|
return true;
|
||||||
|
case ISD::SRL:
|
||||||
|
Hi = DAG.getConstant(0, NVT); // Hi part is zero.
|
||||||
|
Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part.
|
||||||
|
return true;
|
||||||
|
case ISD::SRA:
|
||||||
|
Hi = DAG.getNode(ISD::SRA, NVT, InH, // Sign extend high part.
|
||||||
|
DAG.getConstant(NVTBits-1, Amt.getValueType()));
|
||||||
|
Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we know that the high bit of the shift amount is zero, then we can do
|
||||||
|
// this as a couple of simple shifts.
|
||||||
|
if (KnownZero & Mask) {
|
||||||
|
// Compute 32-amt.
|
||||||
|
SDOperand Amt2 = DAG.getNode(ISD::SUB, Amt.getValueType(),
|
||||||
|
DAG.getConstant(NVTBits, Amt.getValueType()),
|
||||||
|
Amt);
|
||||||
|
|
||||||
|
// Expand the incoming operand to be shifted, so that we have its parts
|
||||||
|
SDOperand InL, InH;
|
||||||
|
ExpandOp(Op, InL, InH);
|
||||||
|
switch(Opc) {
|
||||||
|
case ISD::SHL:
|
||||||
|
Lo = DAG.getNode(ISD::SHL, NVT, InL, Amt);
|
||||||
|
Hi = DAG.getNode(ISD::OR, NVT,
|
||||||
|
DAG.getNode(ISD::SHL, NVT, InH, Amt),
|
||||||
|
DAG.getNode(ISD::SRL, NVT, InL, Amt2));
|
||||||
|
return true;
|
||||||
|
case ISD::SRL:
|
||||||
|
Hi = DAG.getNode(ISD::SRL, NVT, InH, Amt);
|
||||||
|
Lo = DAG.getNode(ISD::OR, NVT,
|
||||||
|
DAG.getNode(ISD::SRL, NVT, InL, Amt),
|
||||||
|
DAG.getNode(ISD::SHL, NVT, InH, Amt2));
|
||||||
|
return true;
|
||||||
|
case ISD::SRA:
|
||||||
|
Hi = DAG.getNode(ISD::SRA, NVT, InH, Amt);
|
||||||
|
Lo = DAG.getNode(ISD::OR, NVT,
|
||||||
|
DAG.getNode(ISD::SRL, NVT, InL, Amt),
|
||||||
|
DAG.getNode(ISD::SHL, NVT, InH, Amt2));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue