[PATCH] D35182: [InstCombine] remove one-use restriction for not (cmp P, A, B) --> cmp P', A, B

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 1 14:44:06 PDT 2017


spatel added a comment.

In https://reviews.llvm.org/D35182#828175, @craig.topper wrote:

> We definitely should do something to fix an invert of a compare feeding an 'and' or 'or' op. I've seen it prevent folding 'and of icmps' or 'or of icmps' because we won't look through the not in those folds. The ones I've seen would have been handled by something like https://reviews.llvm.org/D32725.
>
> This doesn't do anything to fix PR27431 right?




  int a;
  char b;
  int fn1() { return a && b || a && b; }

This eliminates a 'not' op, but doesn't actually solve that example. Currently, we have this at -O2:

  define i32 @fn1(i32 %a, i8 signext %b) {
  entry:
    %tobool = icmp ne i32 %a, 0
    %tobool.not = xor i1 %tobool, true
    %tobool1 = icmp eq i8 %b, 0
    %or.cond = or i1 %tobool1, %tobool.not
    br i1 %or.cond, label %lor.rhs, label %lor.end
  
  lor.rhs:                                          ; preds = %entry
    %tobool4 = icmp ne i8 %b, 0
    %0 = and i1 %tobool, %tobool4
    %phitmp = zext i1 %0 to i32
    br label %lor.end
  
  lor.end:                                          ; preds = %entry, %lor.rhs
    %1 = phi i32 [ %phitmp, %lor.rhs ], [ 1, %entry ]
    ret i32 %1
  }

With this patch applied, we get:

  define i32 @fn1(i32 %a, i8 signext %b)  {
  entry:
    %tobool.not = icmp eq i32 %a, 0
    %tobool1 = icmp eq i8 %b, 0
    %or.cond = or i1 %tobool.not, %tobool1
    br i1 %or.cond, label %lor.rhs, label %lor.end
  
  lor.rhs:                                          ; preds = %entry
    %tobool = icmp ne i32 %a, 0
    %tobool4 = icmp ne i8 %b, 0
    %0 = and i1 %tobool, %tobool4
    %phitmp = zext i1 %0 to i32
    br label %lor.end
  
  lor.end:                                          ; preds = %entry, %lor.rhs
    %1 = phi i32 [ %phitmp, %lor.rhs ], [ 1, %entry ]
    ret i32 %1
  }

This form (more clearly DeMorganized ops) seems easier to have GVN match?

> Do we have any real motivating examples that don't involve the compares being used by bitwise operations that https://reviews.llvm.org/D32725 would take care of?

My motivation is actually PR32706...although I've lost track of how these things actually interact to conflict with each other and infinite loop.


https://reviews.llvm.org/D35182





More information about the llvm-commits mailing list