[llvm] [InstSimplify] Simplify select if it combinated `and/or/xor` (PR #73362)

via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 3 23:52:34 PST 2024


ParkHanbum wrote:

I think this simplification could be changed to:

The X & Y operation is an operator that activates the common bit between the two. Therefore, X & Y == 0 means there are no common bits between the two, ~X belongs to Y, and ~Y belongs to X.

This can be implied and simplified as follows:
```
int src(int x, int y, int c) {
   if (x&y == 0) return (x&c)&y;
   return c;
}

int tgt(int x, int y, int c) {
   if (x&y == 0) return y;
   return c;
}
```
Looking at this in IR, it looks like this.

1. Compiled Basic IR
```
define dso_local i32 @src_curr(i32 noundef %x, i32 noundef %y, i32 noundef %c) #0 {
entry:
   %cmp = icmp eq i32 %y, 0
   %conv = zext i1 %cmp to i32
   %and = and i32 %x, %conv
   %tobool = icmp ne i32 %and, 0
   br i1 %tobool, label %if.then, label %if.end

if.then: ; preds = %entry
   %and1 = and i32 %x, %c
   %and2 = and i32 %and1, %y
   br label %return

if.end: ; preds = %entry
   br label %return

return: ; preds = %if.end, %if.then
   %retval.0 = phi i32 [ %and2, %if.then ], [ %c, %if.end ]
   ret i32 %retval.0
}
```
2. IR after current optimization (optimization level 2-3)
```
define dso_local noundef i32 @tgt_curr(i32 noundef %x, i32 noundef %y, i32 noundef %c) local_unnamed_addr #0 {
entry:
   %cmp = icmp ne i32 %y, 0
   %0 = and i32 %x, 1
   %tobool.not1 = icmp eq i32 %0, 0
   %tobool.not = or i1 %cmp, %tobool.not1
   %and1 = and i32 %y, %x
   %and2 = select i1 %tobool.not, i32 -1, i32 %and1
   %retval.0 = and i32 %and2, %c
   ret i32 %retval.0
}
```
3. Simplify the basic IR as follows
```
define dso_local i32 @tgt_curr_opt(i32 noundef %x, i32 noundef %y, i32 noundef %c) #0 {
entry:
   %cmp = icmp eq i32 %y, 0
   %conv = zext i1 %cmp to i32
   %and = and i32 %x, %conv
   %tobool = icmp ne i32 %and, 0
   br i1 %tobool, label %if.then, label %if.end

if.then: ; preds = %entry
   br label %return

if.end: ; preds = %entry
   br label %return

return: ; preds = %if.end, %if.then
   %retval.0 = phi i32 [ %y, %if.then ], [ %c, %if.end ]
   ret i32 %retval.0
}
```
4. Optimize IR of 3 (Optimization Level 2)
```
define dso_local i32 @tgt_curr_opt(i32 noundef %x, i32 noundef %y, i32 noundef %c) #0 {
entry:
   %cmp = icmp ne i32 %y, 0
   %0 = and i32 %x, 1
   %tobool.not1 = icmp eq i32 %0, 0
   %tobool.not = or i1 %cmp, %tobool.not1
   %y.c = select i1 %tobool.not, i32 %c, i32 %y
   ret i32 %y.c
}
```
attaching the alive2 refer for this.
https://alive2.llvm.org/ce/z/vw2LhP

https://github.com/llvm/llvm-project/pull/73362


More information about the llvm-commits mailing list