[llvm] e0ce875 - [ValueTracking] Add tests for additional `isKnownNonZero` cases; NFC
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 18 11:45:42 PST 2023
Author: Noah Goldstein
Date: 2023-02-18T13:44:55-06:00
New Revision: e0ce87509b18957fc82dd5b1aa5ad50e81412294
URL: https://github.com/llvm/llvm-project/commit/e0ce87509b18957fc82dd5b1aa5ad50e81412294
DIFF: https://github.com/llvm/llvm-project/commit/e0ce87509b18957fc82dd5b1aa5ad50e81412294.diff
LOG: [ValueTracking] Add tests for additional `isKnownNonZero` cases; NFC
Add cases for the following ops:
- 0-X
- bitreverse(X)
- bswap(X)
- ctpop(X)
- abs(X)
- uadd_sat(X, Y)
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D142827
Added:
llvm/test/Analysis/ValueTracking/known-non-zero.ll
Modified:
Removed:
################################################################################
diff --git a/llvm/test/Analysis/ValueTracking/known-non-zero.ll b/llvm/test/Analysis/ValueTracking/known-non-zero.ll
new file mode 100644
index 0000000000000..013aa0709e60b
--- /dev/null
+++ b/llvm/test/Analysis/ValueTracking/known-non-zero.ll
@@ -0,0 +1,183 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=instsimplify < %s -S | FileCheck %s
+
+declare void @llvm.assume(i1)
+declare i8 @llvm.abs.i8(i8, i1)
+declare i8 @llvm.bitreverse.i8(i8)
+declare i16 @llvm.bswap.i16(i16)
+declare i8 @llvm.ctpop.i8(i8)
+declare <2 x i8> @llvm.uadd.sat.2xi8(<2 x i8>, <2 x i8>)
+declare i8 @llvm.uadd.sat.i8(i8, i8)
+
+;; Throughout use: X > Y || Y == 0 which folds to X > Y iff X known
+;; non-zero. Do this because many of the expressions already have
+;; hardcoded cases for folding Foo(X) == 0 -> X == 0 and we want to
+;; test explicitly that `isKnownNonZero` works.
+
+define i1 @check_neg(i8 %x, i8 %y) {
+; CHECK-LABEL: @check_neg(
+; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[NE]])
+; CHECK-NEXT: [[Z:%.*]] = sub i8 0, [[X]]
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
+; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %ne = icmp ne i8 %x, 0
+ call void @llvm.assume(i1 %ne)
+ %z = sub i8 0, %x
+ %cmp0 = icmp ugt i8 %z, %y
+ %cmp1 = icmp eq i8 %y, 0
+ %r = or i1 %cmp0, %cmp1
+ ret i1 %r
+}
+
+define i1 @check_abs(i8 %x, i8 %y) {
+; CHECK-LABEL: @check_abs(
+; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT: br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]]
+; CHECK: true:
+; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true)
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
+; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: ret i1 [[R]]
+; CHECK: false:
+; CHECK-NEXT: ret i1 [[NE]]
+;
+ %ne = icmp ne i8 %x, 0
+ br i1 %ne, label %true, label %false
+true:
+ %z = call i8 @llvm.abs.i8(i8 %x, i1 true)
+ %cmp0 = icmp ugt i8 %z, %y
+ %cmp1 = icmp eq i8 %y, 0
+ %r = or i1 %cmp0, %cmp1
+ ret i1 %r
+false:
+ ret i1 %ne
+}
+
+define i1 @check_abs_failish(i8 %x, i8 %y) {
+; CHECK-LABEL: @check_abs_failish(
+; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT: br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]]
+; CHECK: false:
+; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true)
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
+; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: ret i1 [[R]]
+; CHECK: true:
+; CHECK-NEXT: ret i1 [[NE]]
+;
+ %ne = icmp ne i8 %x, 0
+ br i1 %ne, label %true, label %false
+false:
+ %z = call i8 @llvm.abs.i8(i8 %x, i1 true)
+ %cmp0 = icmp ugt i8 %z, %y
+ %cmp1 = icmp eq i8 %y, 0
+ %r = or i1 %cmp0, %cmp1
+ ret i1 %r
+true:
+ ret i1 %ne
+}
+
+define i1 @check_bitreverse(i8 %x, i8 %y) {
+; CHECK-LABEL: @check_bitreverse(
+; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[NE]])
+; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[X]])
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
+; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %ne = icmp ne i8 %x, 0
+ call void @llvm.assume(i1 %ne)
+ %z = call i8 @llvm.bitreverse.i8(i8 %x)
+ %cmp0 = icmp ugt i8 %z, %y
+ %cmp1 = icmp eq i8 %y, 0
+ %r = or i1 %cmp0, %cmp1
+ ret i1 %r
+}
+
+define i1 @check_bswap(i16 %x, i16 %y) {
+; CHECK-LABEL: @check_bswap(
+; CHECK-NEXT: [[NE:%.*]] = icmp ne i16 [[X:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[NE]])
+; CHECK-NEXT: [[Z:%.*]] = call i16 @llvm.bswap.i16(i16 [[X]])
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i16 [[Z]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i16 [[Y]], 0
+; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %ne = icmp ne i16 %x, 0
+ call void @llvm.assume(i1 %ne)
+ %z = call i16 @llvm.bswap.i16(i16 %x)
+ %cmp0 = icmp ugt i16 %z, %y
+ %cmp1 = icmp eq i16 %y, 0
+ %r = or i1 %cmp0, %cmp1
+ ret i1 %r
+}
+
+define i1 @check_ctpop(i8 %x, i8 %y) {
+; CHECK-LABEL: @check_ctpop(
+; CHECK-NEXT: [[NE:%.*]] = icmp eq i8 [[X:%.*]], 0
+; CHECK-NEXT: br i1 [[NE]], label [[TRUE:%.*]], label [[FALSE:%.*]]
+; CHECK: true:
+; CHECK-NEXT: ret i1 [[NE]]
+; CHECK: false:
+; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X]])
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
+; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %ne = icmp eq i8 %x, 0
+ br i1 %ne, label %true, label %false
+true:
+ ret i1 %ne
+false:
+ %z = call i8 @llvm.ctpop.i8(i8 %x)
+ %cmp0 = icmp ugt i8 %z, %y
+ %cmp1 = icmp eq i8 %y, 0
+ %r = or i1 %cmp0, %cmp1
+ ret i1 %r
+}
+
+define i1 @check_add_sat(i8 %x, i8 %y, i8 %w) {
+; CHECK-LABEL: @check_add_sat(
+; CHECK-NEXT: [[NE:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT: call void @llvm.assume(i1 [[NE]])
+; CHECK-NEXT: [[Z:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X]], i8 [[Y:%.*]])
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[W:%.*]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[W]], 0
+; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %ne = icmp ne i8 %x, 0
+ call void @llvm.assume(i1 %ne)
+ %z = call i8 @llvm.uadd.sat.i8(i8 %x, i8 %y)
+ %cmp0 = icmp ugt i8 %z, %w
+ %cmp1 = icmp eq i8 %w, 0
+ %r = or i1 %cmp0, %cmp1
+ ret i1 %r
+}
+
+define <2 x i1> @check_add_sat_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %w) {
+; CHECK-LABEL: @check_add_sat_vec(
+; CHECK-NEXT: [[YNZ:%.*]] = or <2 x i8> [[Y:%.*]], <i8 2, i8 1>
+; CHECK-NEXT: [[Z:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[YNZ]])
+; CHECK-NEXT: [[CMP0:%.*]] = icmp ugt <2 x i8> [[Z]], [[W:%.*]]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i8> [[W]], zeroinitializer
+; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[CMP0]], [[CMP1]]
+; CHECK-NEXT: ret <2 x i1> [[R]]
+;
+ %ynz = or <2 x i8> %y, <i8 2, i8 1>
+ %z = call <2 x i8> @llvm.uadd.sat.2xi8(<2 x i8> %x, <2 x i8> %ynz)
+ %cmp0 = icmp ugt <2 x i8> %z, %w
+ %cmp1 = icmp eq <2 x i8> %w, <i8 0, i8 0>
+ %r = or <2 x i1> %cmp0, %cmp1
+ ret <2 x i1> %r
+}
More information about the llvm-commits
mailing list