[PATCH] D60506: [CGP] Make ICMP_EQ use CR result of ICMP_S(L|G)T dominators

Yi-Hong Lyu via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 17 10:37:58 PDT 2019


Yi-Hong.Lyu marked an inline comment as done.
Yi-Hong.Lyu added inline comments.


================
Comment at: llvm/lib/CodeGen/CodeGenPrepare.cpp:1420
+  ICmpInst::Predicate Pred = Cmp->getPredicate();
+  if (Pred != ICmpInst::ICMP_EQ)
+    return false;
----------------
nemanjai wrote:
> Yi-Hong.Lyu wrote:
> > nemanjai wrote:
> > > Why do we restrict this to `EQ` rather than also supporting `NE`? Is this just the canonical form and `NE` never shows up?
> > The pattern we observed that could be optimized is something like:
> > ```
> > Block A:
> > icmp slt i32 %1, 100
> > ...
> > Block B (with A being the single predecessor):
> > icmp eq i32 %1, 100 ; Equality is exactly opposite to SGT.
> > ...
> > ```
> > `icmp ne i32 %1, 100` is not supposed to be there, otherwise it would be a redundant LLVM IR.
> I don't follow why this would be redundant IR.
> ```
> BlockA:
> %cmp1 = icmp slt i32 %1, 100
> br i1 %cmp1, BlockC, BlockB
> 
> BlockB: ; %1 is signed-greater-than-or-equal-to 100
> %cmp2 = icmp ne i32 %1, 100
> br i1 %cmp2, BlockD, BlockE
> ...
> BlockC: ; %1 is signed-less-than 100
> ...
> BlockD: ; %1 is signed-greater-than 100
> ...
> BlockE: ; %1 is equal to 100
> ```
> 
> Of course, if the EQ case is the canonical form, that's a different statement, but I don't think NE is automatically redundant.
After some experiments, I think `EQ` is canonical form and `NE` never shows up. I change your pseudo LLVM IR a little bit to make it work:
```
; ModuleID = '<stdin>'
source_filename = "<stdin>"
target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le-unknown-linux-gnu"

define i64 @icmp_ne(i64 %a, i64 %b) {
BlockA:
  %shl = shl i64 %a, %b
  %cmp1 = icmp slt i64 %shl, 1
  br i1 %cmp1, label %BlockC, label %BlockB

BlockB: ; %1 is signed-greater-than-or-equal-to 1
  %cmp2 = icmp ne i64 %shl, 1
  br i1 %cmp2, label %BlockD, label %BlockE

BlockC: ; %1 is signed-less-than 1
  ret i64 %a

BlockD: ; %1 is signed-greater-than 1
  ret i64 %b

BlockE: ; %1 is equal to 1
  %mul = mul nsw i64 %a, %b
  ret i64 %mul
}
```
However, the `NE` would be  transformed into `EQ` as:
```
$ opt -instcombine -S < icmp_ne.ll -o -
; ModuleID = '<stdin>'
source_filename = "<stdin>"
target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le-unknown-linux-gnu"

define i64 @icmp_ne(i64 %a, i64 %b) {
BlockA:
  %shl = shl i64 %a, %b
  %cmp1 = icmp slt i64 %shl, 1
  br i1 %cmp1, label %BlockC, label %BlockB

BlockB:                                           ; preds = %BlockA
  %cmp2 = icmp eq i64 %shl, 1
  br i1 %cmp2, label %BlockE, label %BlockD

BlockC:                                           ; preds = %BlockA
  ret i64 %a

BlockD:                                           ; preds = %BlockB
  ret i64 %b

BlockE:                                           ; preds = %BlockB
  %mul = mul nsw i64 %a, %b
  ret i64 %mul
}
```


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60506/new/

https://reviews.llvm.org/D60506





More information about the llvm-commits mailing list