[PATCH] D11860: [SCEV] Apply NSW and NUW flags via poison value analysis for sub, mul and shl
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 11 14:55:13 PDT 2015
sanjoy requested changes to this revision.
sanjoy added a comment.
This revision now requires changes to proceed.
Comments inline.
================
Comment at: lib/Analysis/ScalarEvolution.cpp:3378
@@ +3377,3 @@
+ // We will transform LHS - RHS to LHS + (-RHS). Thus we cannot make
+ // use of NUW, since -RHS will unsigned-wrap for any non-zero value.
+ if (maskFlags(Flags, SCEV::FlagNSW) == SCEV::FlagNSW) {
----------------
Any non-zero value except 1. :)
================
Comment at: lib/Analysis/ScalarEvolution.cpp:3380
@@ +3379,3 @@
+ if (maskFlags(Flags, SCEV::FlagNSW) == SCEV::FlagNSW) {
+ // Let M be the minimum representable signed value. Then -RHS
+ // signed-wraps if and only if RHS is M. That can happen even for
----------------
I'm being pedantic here, but the reasoning here may be easier to follow if you write `-Foo` as `-1 * Foo` (assuming that's what you mean).
================
Comment at: lib/Analysis/ScalarEvolution.cpp:3396
@@ +3395,3 @@
+ // while the RHS has no recurrence. If RHS has no recurrence and
+ // we attach NSW to the SCEV for -RHS, then we are stating that
+ // -RHS never wraps anywhere, but we only know that -RHS does
----------------
I did not quite follow the logic here -- what's is the "relevant loop" here? An example will be very useful here.
Also, why don't you need `cast<SCEVAddRecExpr>(RHS)->getLoop() == RelevantLoop`?
================
Comment at: lib/Analysis/ScalarEvolution.cpp:4123
@@ -4096,2 +4122,3 @@
SCEV::NoWrapFlags ScalarEvolution::getNoWrapFlagsFromUB(const Value *V) {
- const BinaryOperator *BinOp = cast<BinaryOperator>(V);
+ const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(V);
+ if (!BinOp) return SCEV::FlagAnyWrap;
----------------
Why is this needed? Aren't we ever only going to pass in `mul`, `sub` and `shl`?
================
Comment at: lib/Analysis/ScalarEvolution.cpp:4237
@@ -4212,10 +4236,3 @@
// formed with operands from AddOps.
- //
- // FIXME: Expand this to sub instructions.
- if (Opcode == Instruction::Add && isa<BinaryOperator>(U)) {
- SCEV::NoWrapFlags Flags = getNoWrapFlagsFromUB(U);
- if (Flags != SCEV::FlagAnyWrap) {
- AddOps.push_back(getAddExpr(getSCEV(U->getOperand(0)),
- getSCEV(U->getOperand(1)), Flags));
- break;
- }
+ const SCEV *RHS = getSCEV(U->getOperand(1));
+ SCEV::NoWrapFlags Flags = getNoWrapFlagsFromUB(U);
----------------
Why not hoist `LHS = getSCEV(U->getOperand(0)` as well?
================
Comment at: lib/Analysis/ScalarEvolution.cpp:4265
@@ +4264,3 @@
+
+ if (auto *OpSCEV = getExistingSCEV(Op)) {
+ MulOps.push_back(OpSCEV);
----------------
I'll be in favor of using `U` here instead of `Op` to be consistent, unless that does not work for some reason.
================
Comment at: lib/Analysis/ScalarEvolution.cpp:4408
@@ -4372,2 +4407,3 @@
APInt::getOneBitSet(BitWidth, SA->getZExtValue()));
- return getMulExpr(getSCEV(U->getOperand(0)), getSCEV(X));
+ return getMulExpr(getSCEV(U->getOperand(0)), getSCEV(X),
+ getNoWrapFlagsFromUB(U));
----------------
Unfortunately, this is not quite right. There are some inconsistencies in the langref that to my knowledge have not yet been fixed: see http://lists.llvm.org/pipermail/llvm-dev/2015-April/084195.html and http://reviews.llvm.org/D8890
http://reviews.llvm.org/D11860
More information about the llvm-commits
mailing list