Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VT/test: pre-commit tests to enable samesign optz #120257

Merged
merged 2 commits into from
Jan 9, 2025

Conversation

artagnon
Copy link
Contributor

@artagnon artagnon commented Dec 17, 2024

Pre-commit some tests in preparation to teach ValueTracking's implied-cond about samesign.

@llvmbot
Copy link
Member

llvmbot commented Dec 17, 2024

@llvm/pr-subscribers-llvm-analysis

Author: Ramkumar Ramachandra (artagnon)

Changes

Pre-commit some tests in preparation to teach ValueTracking's implied-cond about samesign. In case of insufficient test coverage, patches that make functional changes to ValueTracking can add additional tests.

-- 8< --
Can you kindly review this, so I can break up patches from #120120 and send them in parallel, all making changes to this file?


Full diff: https://github.com/llvm/llvm-project/pull/120257.diff

1 Files Affected:

  • (added) llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll (+222)
diff --git a/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll b/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll
new file mode 100644
index 00000000000000..4376d3a0248e18
--- /dev/null
+++ b/llvm/test/Analysis/ValueTracking/implied-condition-samesign.ll
@@ -0,0 +1,222 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=instsimplify -S %s | FileCheck %s
+
+define i1 @incr_sle(i32 %i, i32 %len) {
+; CHECK-LABEL: define i1 @incr_sle(
+; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) {
+; CHECK-NEXT:    [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    [[I_GT_LEN:%.*]] = icmp samesign ugt i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[I_INCR_SGT_LEN:%.*]] = icmp sgt i32 [[I_INCR]], [[LEN]]
+; CHECK-NEXT:    [[RES:%.*]] = icmp sle i1 [[I_INCR_SGT_LEN]], [[I_GT_LEN]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %i.incr = add nsw nuw i32 %i, 1
+  %i.gt.len = icmp samesign ugt i32 %i, %len
+  %i.incr.sgt.len = icmp sgt i32 %i.incr, %len
+  %res = icmp sle i1 %i.incr.sgt.len, %i.gt.len
+  ret i1 %res
+}
+
+define i1 @incr_sge(i32 %i, i32 %len) {
+; CHECK-LABEL: define i1 @incr_sge(
+; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) {
+; CHECK-NEXT:    [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    [[I_LT_LEN:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[I_INCR_SLT_LEN:%.*]] = icmp slt i32 [[I_INCR]], [[LEN]]
+; CHECK-NEXT:    [[RES:%.*]] = icmp sge i1 [[I_INCR_SLT_LEN]], [[I_LT_LEN]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %i.incr = add nsw nuw i32 %i, 1
+  %i.lt.len = icmp samesign ult i32 %i, %len
+  %i.incr.slt.len = icmp slt i32 %i.incr, %len
+  %res = icmp sge i1 %i.incr.slt.len, %i.lt.len
+  ret i1 %res
+}
+
+define i1 @incr_ule(i32 %i, i32 %len) {
+; CHECK-LABEL: define i1 @incr_ule(
+; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) {
+; CHECK-NEXT:    [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    [[I_GT_LEN:%.*]] = icmp samesign ugt i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[I_INCR_SGT_LEN:%.*]] = icmp sgt i32 [[I_INCR]], [[LEN]]
+; CHECK-NEXT:    [[RES:%.*]] = icmp ule i1 [[I_GT_LEN]], [[I_INCR_SGT_LEN]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %i.incr = add nsw nuw i32 %i, 1
+  %i.gt.len = icmp samesign ugt i32 %i, %len
+  %i.incr.sgt.len = icmp sgt i32 %i.incr, %len
+  %res = icmp ule i1 %i.gt.len, %i.incr.sgt.len
+  ret i1 %res
+}
+
+define i1 @incr_uge(i32 %i, i32 %len) {
+; CHECK-LABEL: define i1 @incr_uge(
+; CHECK-SAME: i32 [[I:%.*]], i32 [[LEN:%.*]]) {
+; CHECK-NEXT:    [[I_INCR:%.*]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    [[I_LT_LEN:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[I_INCR_SLT_LEN:%.*]] = icmp slt i32 [[I_INCR]], [[LEN]]
+; CHECK-NEXT:    [[RES:%.*]] = icmp uge i1 [[I_LT_LEN]], [[I_INCR_SLT_LEN]]
+; CHECK-NEXT:    ret i1 [[RES]]
+;
+  %i.incr = add nsw nuw i32 %i, 1
+  %i.lt.len = icmp samesign ult i32 %i, %len
+  %i.incr.slt.len = icmp slt i32 %i.incr, %len
+  %res = icmp uge i1 %i.lt.len, %i.incr.slt.len
+  ret i1 %res
+}
+
+define i1 @sgt_implies_ge_via_assume(i32 %i, i32 %j) {
+; CHECK-LABEL: define i1 @sgt_implies_ge_via_assume(
+; CHECK-SAME: i32 [[I:%.*]], i32 [[J:%.*]]) {
+; CHECK-NEXT:    [[I_SGT_J:%.*]] = icmp sgt i32 [[I]], [[J]]
+; CHECK-NEXT:    call void @llvm.assume(i1 [[I_SGT_J]])
+; CHECK-NEXT:    [[I_GE_J:%.*]] = icmp samesign uge i32 [[I]], [[J]]
+; CHECK-NEXT:    ret i1 [[I_GE_J]]
+;
+  %i.sgt.j = icmp sgt i32 %i, %j
+  call void @llvm.assume(i1 %i.sgt.j)
+  %i.ge.j = icmp samesign uge i32 %i, %j
+  ret i1 %i.ge.j
+}
+
+define i32 @gt_implies_sge_dominating(i32 %a, i32 %len) {
+; CHECK-LABEL: define i32 @gt_implies_sge_dominating(
+; CHECK-SAME: i32 [[A:%.*]], i32 [[LEN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[A_GT_LEN:%.*]] = icmp samesign ugt i32 [[A]], [[LEN]]
+; CHECK-NEXT:    br i1 [[A_GT_LEN]], label %[[TAKEN:.*]], label %[[END:.*]]
+; CHECK:       [[TAKEN]]:
+; CHECK-NEXT:    [[A_SGE_LEN:%.*]] = icmp sge i32 [[A]], [[LEN]]
+; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A_SGE_LEN]], i32 30, i32 0
+; CHECK-NEXT:    ret i32 [[RES]]
+; CHECK:       [[END]]:
+; CHECK-NEXT:    ret i32 -1
+;
+entry:
+  %a.gt.len = icmp samesign ugt i32 %a, %len
+  br i1 %a.gt.len, label %taken, label %end
+
+taken:
+  %a.sge.len = icmp sge i32 %a, %len
+  %res = select i1 %a.sge.len, i32 30, i32 0
+  ret i32 %res
+
+end:
+  ret i32 -1
+}
+
+define i32 @gt_implies_sge_dominating_cr(i32 %a, i32 %len) {
+; CHECK-LABEL: define i32 @gt_implies_sge_dominating_cr(
+; CHECK-SAME: i32 [[A:%.*]], i32 [[LEN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[A_GT_20:%.*]] = icmp samesign ugt i32 [[A]], 20
+; CHECK-NEXT:    br i1 [[A_GT_20]], label %[[TAKEN:.*]], label %[[END:.*]]
+; CHECK:       [[TAKEN]]:
+; CHECK-NEXT:    [[A_SGE_10:%.*]] = icmp sge i32 [[A]], 10
+; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A_SGE_10]], i32 30, i32 0
+; CHECK-NEXT:    ret i32 [[RES]]
+; CHECK:       [[END]]:
+; CHECK-NEXT:    ret i32 -1
+;
+entry:
+  %a.gt.20 = icmp samesign ugt i32 %a, 20
+  br i1 %a.gt.20, label %taken, label %end
+
+taken:
+  %a.sge.10 = icmp sge i32 %a, 10
+  %res = select i1 %a.sge.10, i32 30, i32 0
+  ret i32 %res
+
+end:
+  ret i32 -1
+}
+
+define i32 @sgt_implies_ge_dominating_cr(i32 %a, i32 %len) {
+; CHECK-LABEL: define i32 @sgt_implies_ge_dominating_cr(
+; CHECK-SAME: i32 [[A:%.*]], i32 [[LEN:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[A_SGT_MINUS_10:%.*]] = icmp sgt i32 [[A]], -10
+; CHECK-NEXT:    br i1 [[A_SGT_MINUS_10]], label %[[TAKEN:.*]], label %[[END:.*]]
+; CHECK:       [[TAKEN]]:
+; CHECK-NEXT:    [[A_GE_MINUS_20:%.*]] = icmp samesign uge i32 [[A]], -20
+; CHECK-NEXT:    [[RES:%.*]] = select i1 [[A_GE_MINUS_20]], i32 30, i32 0
+; CHECK-NEXT:    ret i32 [[RES]]
+; CHECK:       [[END]]:
+; CHECK-NEXT:    ret i32 -1
+;
+entry:
+  %a.sgt.minus.10 = icmp sgt i32 %a, -10
+  br i1 %a.sgt.minus.10, label %taken, label %end
+
+taken:
+  %a.ge.minus.20 = icmp samesign uge i32 %a, -20
+  %res = select i1 %a.ge.minus.20, i32 30, i32 0
+  ret i32 %res
+
+end:
+  ret i32 -1
+}
+
+define i32 @gt_sub_nsw(i32 %x, i32 %y) {
+; CHECK-LABEL: define i32 @gt_sub_nsw(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[X_GT_Y:%.*]] = icmp samesign ugt i32 [[X]], [[Y]]
+; CHECK-NEXT:    br i1 [[X_GT_Y]], label %[[TAKEN:.*]], label %[[END:.*]]
+; CHECK:       [[TAKEN]]:
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], 1
+; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[SUB]], -1
+; CHECK-NEXT:    [[ABSCOND:%.*]] = icmp samesign ult i32 [[SUB]], -1
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[ADD]]
+; CHECK-NEXT:    ret i32 [[ABS]]
+; CHECK:       [[END]]:
+; CHECK-NEXT:    ret i32 0
+;
+entry:
+  %x.gt.y = icmp samesign ugt i32 %x, %y
+  br i1 %x.gt.y, label %taken, label %end
+
+taken:
+  %sub = sub nsw i32 %x, %y
+  %add = add nsw i32 %sub, 1
+  %neg = xor i32 %sub, -1
+  %abscond = icmp samesign ult i32 %sub, -1
+  %abs = select i1 %abscond, i32 %neg, i32 %add
+  ret i32 %abs
+
+end:
+  ret i32 0
+}
+
+define i32 @ge_sub_nsw(i32 %x, i32 %y) {
+; CHECK-LABEL: define i32 @ge_sub_nsw(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[X_GE_Y:%.*]] = icmp samesign uge i32 [[X]], [[Y]]
+; CHECK-NEXT:    br i1 [[X_GE_Y]], label %[[TAKEN:.*]], label %[[END:.*]]
+; CHECK:       [[TAKEN]]:
+; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], 1
+; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[SUB]], -1
+; CHECK-NEXT:    [[ABSCOND:%.*]] = icmp samesign ult i32 [[SUB]], -1
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[ABSCOND]], i32 [[NEG]], i32 [[ADD]]
+; CHECK-NEXT:    ret i32 [[ABS]]
+; CHECK:       [[END]]:
+; CHECK-NEXT:    ret i32 0
+;
+entry:
+  %x.ge.y = icmp samesign uge i32 %x, %y
+  br i1 %x.ge.y, label %taken, label %end
+
+taken:
+  %sub = sub nsw i32 %x, %y
+  %add = add nsw i32 %sub, 1
+  %neg = xor i32 %sub, -1
+  %abscond = icmp samesign ult i32 %sub, -1
+  %abs = select i1 %abscond, i32 %neg, i32 %add
+  ret i32 %abs
+
+end:
+  ret i32 0
+}

Pre-commit some tests in preparation to teach ValueTracking's
implied-cond about samesign. In case of insufficient test coverage,
patches that make functional changes to ValueTracking can add additional
tests.
@artagnon
Copy link
Contributor Author

artagnon commented Jan 9, 2025

Gentle ping.

Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks! Might be good to add some variants of the incr tests without nuw/nsw as well?

@artagnon artagnon merged commit 9d5299e into llvm:main Jan 9, 2025
5 of 6 checks passed
@artagnon artagnon deleted the vt-samesign-test branch January 9, 2025 20:18
BaiXilin pushed a commit to BaiXilin/llvm-fix-vnni-instr-types that referenced this pull request Jan 12, 2025
Pre-commit some tests in preparation to teach ValueTracking's
implied-cond about samesign.
Mel-Chen pushed a commit to Mel-Chen/llvm-project that referenced this pull request Jan 13, 2025
Pre-commit some tests in preparation to teach ValueTracking's
implied-cond about samesign.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants