[llvm] [InstCombine] Fold `icmp eq/ne (X and C), 0` when partial bits are known (PR #85863)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 19 14:16:59 PDT 2024
================
@@ -403,3 +403,88 @@ truelabel:
falselabel:
ret i8 0
}
+
+define i1 @and_mask1_eq(i32 %conv) {
+; CHECK-LABEL: @and_mask1_eq(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: ret i1 false
+; CHECK: else:
+; CHECK-NEXT: call void @dummy()
+; CHECK-NEXT: ret i1 false
+;
+entry:
+ %and = and i32 %conv, 1
+ %cmp = icmp eq i32 %and, 0
+ br i1 %cmp, label %then, label %else
+
+then:
+ ret i1 0
+
+else:
+ call void @dummy()
+ %and1 = and i32 %conv, 3
+ %cmp1 = icmp eq i32 %and1, 0
+ ret i1 %cmp1
+}
+
+define i1 @and_mask1_ne(i32 %conv) {
+; CHECK-LABEL: @and_mask1_ne(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: ret i1 false
+; CHECK: else:
+; CHECK-NEXT: call void @dummy()
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %and = and i32 %conv, 1
+ %cmp = icmp eq i32 %and, 0
+ br i1 %cmp, label %then, label %else
+
+then:
+ ret i1 0
+
+else:
+ call void @dummy()
+ %and1 = and i32 %conv, 3
+ %cmp1 = icmp ne i32 %and1, 0
+ ret i1 %cmp1
+}
+
+define i1 @and_mask2(i32 %conv) {
+; CHECK-LABEL: @and_mask2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: ret i1 false
+; CHECK: else:
+; CHECK-NEXT: call void @dummy()
+; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 3
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0
+; CHECK-NEXT: ret i1 [[CMP1]]
+;
+entry:
+ %and = and i32 %conv, 4
+ %cmp = icmp eq i32 %and, 0
+ br i1 %cmp, label %then, label %else
+
+then:
+ ret i1 0
+
+else:
+ call void @dummy()
+ %and1 = and i32 %conv, 3
+ %cmp1 = icmp eq i32 %and1, 0
+ ret i1 %cmp1
+}
+
+declare void @dummy()
----------------
nikic wrote:
I'd add another test along these lines:
```
define i1 @src(i32 %conv) {
entry:
%and = and i32 %conv, 3
%cmp = icmp eq i32 %and, 0
br i1 %cmp, label %then, label %else
then:
ret i1 0
else:
%and1 = and i32 %conv, 7
%cmp1 = icmp eq i32 %and1, 0
ret i1 %cmp1
}
```
This *could* be folded, but I believe isn't by your patch. (As it relies on known one bits, rather than "one of these bits is non-zero".)
https://github.com/llvm/llvm-project/pull/85863
More information about the llvm-commits
mailing list