diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp @@ -1005,6 +1005,16 @@ 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 *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;