[llvm] 4b7d51f - [InstCombine] add baseline tests for signbit cmp folds; NFC

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 19 06:04:45 PDT 2022


Author: Eric Gullufsen
Date: 2022-06-19T09:03:28-04:00
New Revision: 4b7d51f129f0f41cf270d7f83c094908cb3f008f

URL: https://github.com/llvm/llvm-project/commit/4b7d51f129f0f41cf270d7f83c094908cb3f008f
DIFF: https://github.com/llvm/llvm-project/commit/4b7d51f129f0f41cf270d7f83c094908cb3f008f.diff

LOG: [InstCombine] add baseline tests for signbit cmp folds; NFC

D127903 / issue #55988

Added: 
    

Modified: 
    llvm/test/Transforms/InstCombine/and-or-icmps.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
index d8629ed7dc867..5a752aa93fa51 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -2,6 +2,7 @@
 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
 
 declare void @use(i1)
+declare void @use32(i32)
 
 define i1 @PR1817_1(i32 %X) {
 ; CHECK-LABEL: @PR1817_1(
@@ -2098,3 +2099,392 @@ define i1 @bitwise_and_logical_and_masked_icmp_allones_poison2(i1 %c, i32 %x, i3
   %and2 = and i1 %and1, %c2
   ret i1 %and2
 }
+
+define i1 @samesign(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %lt = icmp slt i32 %a, 0
+  %o = or i32 %x, %y
+  %gt = icmp sgt i32 %o, -1
+  %r = or i1 %lt, %gt
+  ret i1 %r
+}
+
+define i1 @samesign_
diff erent_sign_bittest1(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_
diff erent_sign_bittest1(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %lt = icmp sle i32 %a, -1
+  %o = or i32 %x, %y
+  %gt = icmp sgt i32 %o, -1
+  %r = or i1 %lt, %gt
+  ret i1 %r
+}
+
+define i1 @samesign_
diff erent_sign_bittest2(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_
diff erent_sign_bittest2(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %lt = icmp slt i32 %a, 0
+  %o = or i32 %x, %y
+  %gt = icmp sge i32 %o, 0
+  %r = or i1 %lt, %gt
+  ret i1 %r
+}
+
+define i1 @samesign_commute1(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_commute1(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %lt = icmp slt i32 %a, 0
+  %o = or i32 %x, %y
+  %gt = icmp sgt i32 %o, -1
+  %r = or i1 %gt, %lt ; compares swapped
+  ret i1 %r
+}
+
+define i1 @samesign_commute2(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_commute2(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[Y]], [[X]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %lt = icmp slt i32 %a, 0
+  %o = or i32 %y, %x ; inputs commuted
+  %gt = icmp sgt i32 %o, -1
+  %r = or i1 %lt, %gt
+  ret i1 %r
+}
+
+define i1 @samesign_commute3(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_commute3(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[Y]], [[X]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %lt = icmp slt i32 %a, 0
+  %o = or i32 %y, %x ; inputs commuted
+  %gt = icmp sgt i32 %o, -1
+  %r = or i1 %gt, %lt ; compares swapped
+  ret i1 %r
+}
+
+define i1 @samesign_violate_constraint1(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_violate_constraint1(
+; CHECK-NEXT:    [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = or i32 %x, %y
+  %lt = icmp slt i32 %a, 0
+  %o = or i32 %x, %y ; should be an and
+  %gt = icmp sgt i32 %o, -1
+  %r = and i1 %lt, %gt
+  ret i1 %r
+}
+
+define i1 @samesign_violate_constraint2(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_violate_constraint2(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %lt = icmp slt i32 %a, 0
+  %o = or i32 %x, %y
+  %gt = icmp sgt i32 %o, -1
+  %r = and i1 %lt, %gt ; should be or
+  ret i1 %r
+}
+
+define i1 @samesign_mult_use(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_mult_use(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use32(i32 [[A]])
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    call void @use32(i32 [[O]])
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  call void @use32(i32 %a)
+  %lt = icmp slt i32 %a, 0
+  %o = or i32 %x, %y
+  call void @use32(i32 %o)
+  %gt = icmp sgt i32 %o, -1
+  %r = and i1 %lt, %gt
+  ret i1 %r
+}
+
+define i1 @samesign_mult_use2(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_mult_use2(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 0
+; CHECK-NEXT:    call void @use(i1 [[LT]])
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    call void @use(i1 [[GT]])
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %lt = icmp slt i32 %a, 0
+  call void @use(i1 %lt)
+  %o = or i32 %x, %y
+  %gt = icmp sgt i32 %o, -1
+  call void @use(i1 %gt)
+  %r = and i1 %lt, %gt
+  ret i1 %r
+}
+
+define i1 @samesign_wrong_cmp(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_wrong_cmp(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[A]], 1
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[O]], -1
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %lt = icmp slt i32 %a, 1 ; not a sign-bit test
+  %o = or i32 %x, %y
+  %gt = icmp sgt i32 %o, -1
+  %r = and i1 %lt, %gt
+  ret i1 %r
+}
+
+define i1 @samesign_inverted(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %gt = icmp sgt i32 %a, -1
+  %o = or i32 %x, %y
+  %lt = icmp slt i32 %o, 0
+  %r = and i1 %gt, %lt
+  ret i1 %r
+}
+
+define i1 @samesign_inverted_
diff erent_sign_bittest1(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_
diff erent_sign_bittest1(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %gt = icmp sge i32 %a, 0
+  %o = or i32 %x, %y
+  %lt = icmp slt i32 %o, 0
+  %r = and i1 %gt, %lt
+  ret i1 %r
+}
+
+define i1 @samesign_inverted_
diff erent_sign_bittest2(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_
diff erent_sign_bittest2(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %gt = icmp sgt i32 %a, -1
+  %o = or i32 %x, %y
+  %lt = icmp sle i32 %o, -1
+  %r = and i1 %gt, %lt
+  ret i1 %r
+}
+
+define i1 @samesign_inverted_commute1(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_commute1(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %gt = icmp sgt i32 %a, -1
+  %o = or i32 %x, %y
+  %lt = icmp slt i32 %o, 0
+  %r = and i1 %lt, %gt ; compares swapped
+  ret i1 %r
+}
+
+define i1 @samesign_inverted_commute2(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_commute2(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[Y]], [[X]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %gt = icmp sgt i32 %a, -1
+  %o = or i32 %y, %x ; source values are commuted
+  %lt = icmp slt i32 %o, 0
+  %r = and i1 %gt, %lt
+  ret i1 %r
+}
+
+define i1 @samesign_inverted_commute3(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_commute3(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[Y]], [[X]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[LT]], [[GT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %gt = icmp sgt i32 %a, -1
+  %o = or i32 %y, %x ; source values commuted
+  %lt = icmp slt i32 %o, 0
+  %r = and i1 %lt, %gt ; compares swapped
+  ret i1 %r
+}
+
+define i1 @samesign_inverted_violate_constraint1(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_violate_constraint1(
+; CHECK-NEXT:    [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    [[O:%.*]] = and i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = or i32 %x, %y ; should be and here
+  %gt = icmp sgt i32 %a, -1
+  %o = and i32 %x, %y ; should be or here
+  %lt = icmp slt i32 %o, 0
+  %r = and i1 %gt, %lt
+  ret i1 %r
+}
+define i1 @samesign_inverted_violate_constraint2(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_violate_constraint2(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = or i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %gt = icmp sgt i32 %a, -1
+  %o = or i32 %x, %y
+  %lt = icmp slt i32 %o, 0
+  %r = or i1 %gt, %lt ; should be and here
+  ret i1 %r
+}
+
+define i1 @samesign_inverted_mult_use(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_mult_use(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    call void @use32(i32 [[A]])
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    call void @use32(i32 [[O]])
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  call void @use32(i32 %a)
+  %gt = icmp sgt i32 %a, -1
+  %o = or i32 %x, %y
+  call void @use32(i32 %o)
+  %lt = icmp slt i32 %o, 0
+  %r = and i1 %gt, %lt
+  ret i1 %r
+}
+
+define i1 @samesign_inverted_mult_use2(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_mult_use2(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    call void @use(i1 [[GT]])
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    call void @use(i1 [[LT]])
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %gt = icmp sgt i32 %a, -1
+  call void @use(i1 %gt)
+  %o = or i32 %x, %y
+  %lt = icmp slt i32 %o, 0
+  call void @use(i1 %lt)
+  %r = and i1 %gt, %lt
+  ret i1 %r
+}
+
+define i1 @samesign_inverted_wrong_cmp(i32 %x, i32 %y) {
+; CHECK-LABEL: @samesign_inverted_wrong_cmp(
+; CHECK-NEXT:    [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[A]], 0
+; CHECK-NEXT:    [[O:%.*]] = or i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[LT:%.*]] = icmp slt i32 [[O]], 0
+; CHECK-NEXT:    [[R:%.*]] = and i1 [[GT]], [[LT]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %a = and i32 %x, %y
+  %gt = icmp sgt i32 %a, 0 ; not a sign-bit test
+  %o = or i32 %x, %y
+  %lt = icmp slt i32 %o, 0
+  %r = and i1 %gt, %lt
+  ret i1 %r
+}


        


More information about the llvm-commits mailing list