[AMDGPU] Try to determine sign bit during div/rem expansion

This is preparation for D79294, which removes an expensive
InstSimplify optimization, on the assumption that it will be
picked up by InstCombine instead. Of course, this does not hold
up if a backend performs non-trivial IR expansions without running
a canonicalization pipeline afterwards, which turned up as an
issue in the context of AMDGPU div/rem expansion.

This patch mitigates the issue by explicitly performing a known
bits calculation where it matters. No test changes, as those would
only be visible after the other patch lands.

Differential Revision: https://reviews.llvm.org/D79596
This commit is contained in:
Nikita Popov 2020-05-07 22:42:18 +02:00
parent a60baef666
commit fd1a3e0dc7

View File

@ -1005,6 +1005,16 @@ bool AMDGPUCodeGenPrepare::divHasSpecialOptimization(
return false;
}
static Value *getSign32(Value *V, IRBuilder<> &Builder, const DataLayout *DL) {
// Check whether the sign can be determined statically.
KnownBits Known = computeKnownBits(V, *DL);
if (Known.isNegative())
return Constant::getAllOnesValue(V->getType());
if (Known.isNonNegative())
return Constant::getNullValue(V->getType());
return Builder.CreateAShr(V, Builder.getInt32(31));
}
Value* AMDGPUCodeGenPrepare::expandDivRem32(IRBuilder<> &Builder,
BinaryOperator &I,
Value *Num, Value *Den) const {
@ -1046,9 +1056,8 @@ Value* AMDGPUCodeGenPrepare::expandDivRem32(IRBuilder<> &Builder,
Value *Sign = nullptr;
if (IsSigned) {
ConstantInt *K31 = Builder.getInt32(31);
Value *LHSign = Builder.CreateAShr(Num, K31);
Value *RHSign = Builder.CreateAShr(Den, K31);
Value *LHSign = getSign32(Num, Builder, DL);
Value *RHSign = getSign32(Den, Builder, DL);
// Remainder sign is the same as LHS
Sign = IsDiv ? Builder.CreateXor(LHSign, RHSign) : LHSign;