[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