Multiply and shl have different signed overflow behavior in
some cases. But it looks like we should be ok as long as the
shift amount is less than bitwidth - 1.
Details
Details
Diff Detail
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Comment Actions
Grepping a bit, there's this:
const SCEV *ScalarEvolution::createSCEV(Value *V) { <...> case Instruction::Shl: // Turn shift left of a constant amount into a multiply. if (ConstantInt *SA = dyn_cast<ConstantInt>(BO->RHS)) { uint32_t BitWidth = cast<IntegerType>(SA->getType())->getBitWidth(); // If the shift count is not less than the bitwidth, the result of // the shift is undefined. Don't try to analyze it, because the // resolution chosen here may differ from the resolution chosen in // other parts of the compiler. if (SA->getValue().uge(BitWidth)) break; // It is currently not resolved how to interpret NSW for left // shift by BitWidth - 1, so we avoid applying flags in that // case. Remove this check (or this comment) once the situation // is resolved. See // http://lists.llvm.org/pipermail/llvm-dev/2015-April/084195.html // and http://reviews.llvm.org/D8890 . auto Flags = SCEV::FlagAnyWrap; if (BO->Op && SA->getValue().ult(BitWidth - 1)) Flags = getNoWrapFlagsFromUB(BO->Op); Constant *X = ConstantInt::get( getContext(), APInt::getOneBitSet(BitWidth, SA->getZExtValue())); return getMulExpr(getSCEV(BO->LHS), getSCEV(X), Flags); } break;
But apparently langref was fixed in rL286785, so we're good and i'll post SCEV patch.