[llvm] [InstCombine] Try optimizing with knownbits which determined from Cond (PR #91762)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 17 08:05:40 PDT 2024
================
@@ -1809,6 +1809,198 @@ static Instruction *foldSelectICmpEq(SelectInst &SI, ICmpInst *ICI,
return nullptr;
}
+// ICmpInst of SelectInst is not included in the calculation of KnownBits
+// so we are missing the opportunity to optimize the Value of the True or
+// False Condition via ICmpInst with KnownBits.
+//
+// Consider:
+// %or = or i32 %x, %y
+// %or0 = icmp eq i32 %or, 0
+// %and = and i32 %x, %y
+// %cond = select i1 %or0, i32 %and, i32 %or
+// ret i32 %cond
+//
+// Expect:
+// %or = or i32 %x, %y
+// ret i32 %or
+//
+// We could know what bit was enabled for %x, %y by ICmpInst in SelectInst.
+static Instruction *foldSelectICmpBinOp(SelectInst &SI, ICmpInst *ICI,
+ Value *CmpLHS, Value *CmpRHS,
+ Value *TVal, Value *FVal,
+ InstCombinerImpl &IC) {
----------------
ParkHanbum wrote:
sorry, I didn't understood what is your point. would you explain more detail for newbie?
as I know, swap of true and false need to swap compare also. so, we test "equal" compare changed to "not equal" for cases of each. and we also test exchange %x, %y.
this is added tests with this commit:
```
define i32 @src_or_disjoint_xor(i32 %x, i32 %y) {
; CHECK-LABEL: @src_or_disjoint_xor(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 -1
;
entry:
%or.disjoint = or disjoint i32 %x, %y
%cmp = icmp eq i32 %or.disjoint, -1
%xor = xor i32 %x, %y
%cond = select i1 %cmp, i32 %xor, i32 -1
ret i32 %cond
}
define i32 @src_or_disjoint_xor_comm(i32 %x, i32 %y) {
; CHECK-LABEL: @src_or_disjoint_xor_comm(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 -1
;
entry:
%or.disjoint = or disjoint i32 %y, %x
%cmp = icmp eq i32 -1, %or.disjoint
%xor = xor i32 %y, %x
%cond = select i1 %cmp, i32 %xor, i32 -1
ret i32 %cond
}
define i32 @src_or_disjoint_xor_ne(i32 %x, i32 %y) {
; CHECK-LABEL: @src_or_disjoint_xor_ne(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 -1
;
entry:
%or.disjoint = or disjoint i32 %x, %y
%cmp = icmp ne i32 %or.disjoint, -1
%xor = xor i32 %x, %y
%cond = select i1 %cmp, i32 -1, i32 %xor
ret i32 %cond
}
define i32 @src_or_disjoint_xor_ne_comm(i32 %x, i32 %y) {
; CHECK-LABEL: @src_or_disjoint_xor_ne_comm(
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 -1
;
entry:
%or.disjoint = or disjoint i32 %y, %x
%cmp = icmp ne i32 %or.disjoint, -1
%xor = xor i32 %y, %x
%cond = select i1 %cmp, i32 -1, i32 %xor
ret i32 %cond
}
```
if you explain what you considering then it very helpful for me to improve knowledge of llvm.
https://github.com/llvm/llvm-project/pull/91762
More information about the llvm-commits
mailing list