[PATCH] D32725: [InstCombine] Apply deMorgan to (and/or (not cmp1), cmp2) when cmp1 has multiple uses, but cmp2 has a single use

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 3 15:57:10 PDT 2017


spatel added a comment.

In https://reviews.llvm.org/D32725#744881, @craig.topper wrote:

> should we also lift the one use check for compares in IsFreeToInvert?


Yes, I think that makes sense. @efriedma - do you foresee problems?
I forgot that I already filed this bug that will result if we lift the one-use restriction for // xor (cmp A, B), true = not (cmp A, B) = !cmp A, B :
https://bugs.llvm.org/show_bug.cgi?id=32791

> What about floating point compares? We probably don't have as many folds for them.

IMO, it's just a bonus that we have lots of icmp folds. The main reason we should not care about uses for these folds is that we always reduce the dependency chain by inverting the predicate. If we're missing folds based on inverted predicates, we can add those (and might need to do that first to avoid regressions). If either icmp or fcmp is less efficient than 'not' for some target, then it can invert this in the backend.

Examples:

  declare void @bar(i1, i1)
  
  define void @icmp_neg(i8 %a) {
    %cmp = icmp eq i8 %a, 1
    %neg = xor i1 %cmp, -1  <--- must wait for cmp
    call void @bar(i1 %cmp, i1 %neg)
    ret void
  }
  
  define void @icmp_inv(i8 %a) {
    %cmp = icmp eq i8 %a, 1
    %neg = icmp ne i8 %a, 1    <--- can execute immediately
    call void @bar(i1 %cmp, i1 %neg)
    ret void
  }
  
  define void @fcmp_neg(float %a) {
    %cmp = fcmp oeq float %a, 1.0
    %neg = xor i1 %cmp, -1
    call void @bar(i1 %cmp, i1 %neg)
    ret void
  }
  
  define void @fcmp_inv(float %a) {
    %cmp = fcmp oeq float %a, 1.0
    %neg = fcmp une float %a, 1.0
    call void @bar(i1 %cmp, i1 %neg)
    ret void
  }


https://reviews.llvm.org/D32725





More information about the llvm-commits mailing list