[PATCH] D12073: Make ScalarEvolution::isKnownPredicate a little smarter

hfinkel@anl.gov via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 17 10:16:38 PDT 2015


hfinkel added a comment.

In http://reviews.llvm.org/D12073#225873, @sanjoy wrote:

> I'd solve this differently -- if I understand the problem correctly, you should really only need to teach SCEV that `{0,+,1}<nsw>` is `slt` `{1,+,1}<nsw>` (or something similar to that) in `isImpliedCondOperandsHelper`.


That's correct (but it triggers in some other cases too); I need to look at this in more detail, but a quick check reveals that for this code:

  $ cat /tmp/t.c
  void foo (int *a, int *b, int n) {
    for (int i = 0; i < n; ++i) {
      if (i > n)
        a[i] = b[i] + 1;
    }
  }

these statements trigger to do the following:

- proving that {0,+,1}<nuw><nsw><%for.body> sle {1,+,1}<nuw><nsw><%for.body> (the subtraction simplifies to -1)
- proving that (sext i32 %n to i64) sle (1 + (sext i32 %n to i64))<nsw> (again, the subtraction simplifies to -1)

for this code (which differs from the above only by the +4):

  $ cat /tmp/t4.c
  void foo (int *a, int *b, int n) {
    for (int i = 0; i < n; ++i) {
      if (i > n + 4)
        a[i] = b[i] + 1;
    }
  }

this code is used to:

- prove that %n sle (4 + %n) (the subtraction simplifies to -4)
- prove that {0,+,1}<nuw><nsw><%for.body> sle {1,+,1}<nuw><nsw><%for.body> (the subtraction simplifies to -1)

In the pr17473.ll test case, the statements trigger to:

- prove that 0 sle {1,+,1}<%for.body> (the subtraction simplifies to {-1,+,-1}<%for.body>
- prove that 127 sle {-2,+,-1}<%for.body> (the subtraction simplifies to {-127,+,1}<%for.body>)

That last one does indeed seem wrong (certainly justifying your point below).


================
Comment at: lib/Analysis/ScalarEvolution.cpp:6873
@@ -6872,3 +6872,3 @@
 bool
 ScalarEvolution::isKnownPredicateWithRanges(ICmpInst::Predicate Pred,
                                             const SCEV *LHS, const SCEV *RHS) {
----------------
sanjoy wrote:
> This should probably live in `ScalarEvolution::isKnownPredicate` or `ScalarEvolution::isImpliedCondOperandsHelper`, not here.
I put these here as they exactly mirror the check done below as part of the ICmpInst::ICMP_NE case below (which could certainly also be moved if we'd like).


================
Comment at: lib/Analysis/ScalarEvolution.cpp:6892
@@ -6891,1 +6891,3 @@
       return false;
+
+    const SCEV *Diff = getMinusSCEV(LHS, RHS);
----------------
sanjoy wrote:
> I'm not sure this is sound w.r.t. overflow.  For instance, if `LHS` = `i8 127` and `RHS` = `i8 -1` then `!(LHS < RHS)` but `LHS - RHS = i8 128 < 0`
This is precisely what was worrying me w.r.t. to correctness, and given the output, it seems this is exactly what happens. Sign-extending first would fix that, right?


Repository:
  rL LLVM

http://reviews.llvm.org/D12073





More information about the llvm-commits mailing list