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

[Reassociate] Adds test coverage for reassociation of scalar & vector boolean types #89899

Merged
merged 4 commits into from
May 7, 2024

Conversation

SahilPatidar
Copy link
Contributor

@SahilPatidar SahilPatidar commented Apr 24, 2024

First step for #64840

@SahilPatidar
Copy link
Contributor Author

@RKSimon, Let me know if any of the tests make sense to you.

@RKSimon RKSimon requested review from nikic, RKSimon and dtcxzyw May 2, 2024 16:52
@RKSimon RKSimon marked this pull request as ready for review May 2, 2024 16:55
@llvmbot
Copy link
Collaborator

llvmbot commented May 2, 2024

@llvm/pr-subscribers-llvm-transforms

Author: None (SahilPatidar)

Changes

Resolve #64840


Patch is 24.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/89899.diff

2 Files Affected:

  • (added) llvm/test/Transforms/Reassociate/reassoc_bool.ll (+223)
  • (added) llvm/test/Transforms/Reassociate/reassoc_bool_vec.ll (+281)
diff --git a/llvm/test/Transforms/Reassociate/reassoc_bool.ll b/llvm/test/Transforms/Reassociate/reassoc_bool.ll
new file mode 100644
index 00000000000000..a4987111bc16a3
--- /dev/null
+++ b/llvm/test/Transforms/Reassociate/reassoc_bool.ll
@@ -0,0 +1,223 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -passes=reassociate -S | FileCheck %s
+
+define i1 @scalar(i32 %a, i32 %b0, i32 %b1, i32 %b2, i32 %b3, i32 %b4, i32 %b5, i32 %b6, i32 %b7) local_unnamed_addr {
+; CHECK-LABEL: define i1 @scalar(
+; CHECK-SAME: i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[B1:%.*]], i32 [[B2:%.*]], i32 [[B3:%.*]], i32 [[B4:%.*]], i32 [[B5:%.*]], i32 [[B6:%.*]], i32 [[B7:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[B0]], [[A]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[B1]], [[A]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[B2]], [[A]]
+; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i32 [[B3]], [[A]]
+; CHECK-NEXT:    [[CMP4:%.*]] = icmp eq i32 [[B4]], [[A]]
+; CHECK-NEXT:    [[CMP5:%.*]] = icmp eq i32 [[B5]], [[A]]
+; CHECK-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[B6]], [[A]]
+; CHECK-NEXT:    [[CMP7:%.*]] = icmp eq i32 [[B7]], [[A]]
+; CHECK-NEXT:    [[OR01:%.*]] = or i1 [[CMP0]], [[CMP1]]
+; CHECK-NEXT:    [[OR23:%.*]] = or i1 [[CMP2]], [[CMP3]]
+; CHECK-NEXT:    [[OR45:%.*]] = or i1 [[CMP4]], [[CMP5]]
+; CHECK-NEXT:    [[OR67:%.*]] = or i1 [[CMP6]], [[CMP7]]
+; CHECK-NEXT:    [[OR0123:%.*]] = or i1 [[OR01]], [[OR23]]
+; CHECK-NEXT:    [[OR4567:%.*]] = or i1 [[OR45]], [[OR67]]
+; CHECK-NEXT:    [[OR01234567:%.*]] = or i1 [[OR0123]], [[OR4567]]
+; CHECK-NEXT:    ret i1 [[OR01234567]]
+;
+  %cmp0 = icmp eq i32 %b0, %a
+  %cmp1 = icmp eq i32 %b1, %a
+  %cmp2 = icmp eq i32 %b2, %a
+  %cmp3 = icmp eq i32 %b3, %a
+  %cmp4 = icmp eq i32 %b4, %a
+  %cmp5 = icmp eq i32 %b5, %a
+  %cmp6 = icmp eq i32 %b6, %a
+  %cmp7 = icmp eq i32 %b7, %a
+  %or01 = or i1 %cmp0, %cmp1
+  %or23 = or i1 %cmp2, %cmp3
+  %or45 = or i1 %cmp4, %cmp5
+  %or67 = or i1 %cmp6, %cmp7
+  %or0123 = or i1 %or01, %or23
+  %or4567 = or i1 %or45, %or67
+  %or01234567 = or i1 %or0123, %or4567
+  ret i1 %or01234567
+}
+
+
+define i1 @scalar1(i1 %a, i1 %b0, i1 %b1, i1 %b2, i1 %b3, i1 %b4, i1 %b5, i1 %b6, i1 %b7) local_unnamed_addr {
+; CHECK-LABEL: define i1 @scalar1(
+; CHECK-SAME: i1 [[A:%.*]], i1 [[B0:%.*]], i1 [[B1:%.*]], i1 [[B2:%.*]], i1 [[B3:%.*]], i1 [[B4:%.*]], i1 [[B5:%.*]], i1 [[B6:%.*]], i1 [[B7:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[OR0:%.*]] = or i1 [[A]], [[B0]]
+; CHECK-NEXT:    [[OR1:%.*]] = or i1 [[A]], [[B1]]
+; CHECK-NEXT:    [[OR2:%.*]] = or i1 [[A]], [[B2]]
+; CHECK-NEXT:    [[OR3:%.*]] = or i1 [[A]], [[B3]]
+; CHECK-NEXT:    [[OR4:%.*]] = or i1 [[A]], [[B4]]
+; CHECK-NEXT:    [[OR5:%.*]] = or i1 [[A]], [[B5]]
+; CHECK-NEXT:    [[OR6:%.*]] = or i1 [[A]], [[B6]]
+; CHECK-NEXT:    [[OR7:%.*]] = or i1 [[A]], [[B7]]
+; CHECK-NEXT:    [[XOR0:%.*]] = xor i1 [[OR0]], [[OR1]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i1 [[XOR0]], [[OR2]]
+; CHECK-NEXT:    [[XOR2:%.*]] = xor i1 [[XOR1]], [[OR3]]
+; CHECK-NEXT:    [[XOR3:%.*]] = xor i1 [[XOR2]], [[OR4]]
+; CHECK-NEXT:    [[XOR4:%.*]] = xor i1 [[XOR3]], [[OR5]]
+; CHECK-NEXT:    [[XOR5:%.*]] = xor i1 [[XOR4]], [[OR6]]
+; CHECK-NEXT:    [[XOR6:%.*]] = xor i1 [[XOR5]], [[OR7]]
+; CHECK-NEXT:    [[OR001:%.*]] = or i1 [[XOR0]], [[XOR1]]
+; CHECK-NEXT:    [[OR023:%.*]] = or i1 [[XOR2]], [[XOR3]]
+; CHECK-NEXT:    [[OR045:%.*]] = or i1 [[XOR4]], [[XOR5]]
+; CHECK-NEXT:    [[OR060:%.*]] = or i1 [[XOR0]], [[XOR6]]
+; CHECK-NEXT:    [[OR0123:%.*]] = or i1 [[OR001]], [[OR023]]
+; CHECK-NEXT:    [[OR4560:%.*]] = or i1 [[OR045]], [[OR060]]
+; CHECK-NEXT:    [[OR01234567:%.*]] = or i1 [[OR0123]], [[OR4560]]
+; CHECK-NEXT:    ret i1 [[OR01234567]]
+;
+  %or0 = or i1 %b0, %a
+  %or1 = or i1 %b1, %a
+  %or2 = or i1 %b2, %a
+  %or3 = or i1 %b3, %a
+  %or4 = or i1 %b4, %a
+  %or5 = or i1 %b5, %a
+  %or6 = or i1 %b6, %a
+  %or7 = or i1 %b7, %a
+  %xor0 = xor i1 %or0, %or1
+  %xor1 = xor i1 %xor0, %or2
+  %xor2 = xor i1 %xor1, %or3
+  %xor3 = xor i1 %xor2, %or4
+  %xor4 = xor i1 %xor3, %or5
+  %xor5 = xor i1 %xor4, %or6
+  %xor6 = xor i1 %xor5, %or7
+  %or001 = or i1 %xor0, %xor1
+  %or023 = or i1 %xor2, %xor3
+  %or045 = or i1 %xor4, %xor5
+  %or060 = or i1 %xor6, %xor0
+  %or0123 = or i1 %or001, %or023
+  %or4560 = or i1 %or045, %or060
+  %or01234567 = or i1 %or0123, %or4560
+  ret i1 %or01234567
+}
+
+define i1 @scalar2(i1 %a, i1 %b0, i1 %b1, i1 %b2, i1 %b3, i1 %b4, i1 %b5, i1 %b6, i1 %b7) local_unnamed_addr {
+; CHECK-LABEL: define i1 @scalar2(
+; CHECK-SAME: i1 [[A:%.*]], i1 [[B0:%.*]], i1 [[B1:%.*]], i1 [[B2:%.*]], i1 [[B3:%.*]], i1 [[B4:%.*]], i1 [[B5:%.*]], i1 [[B6:%.*]], i1 [[B7:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[OR0:%.*]] = or i1 [[A]], [[B0]]
+; CHECK-NEXT:    [[OR1:%.*]] = or i1 [[A]], [[B1]]
+; CHECK-NEXT:    [[OR2:%.*]] = or i1 [[A]], [[B2]]
+; CHECK-NEXT:    [[OR3:%.*]] = or i1 [[A]], [[B3]]
+; CHECK-NEXT:    [[OR4:%.*]] = or i1 [[A]], [[B4]]
+; CHECK-NEXT:    [[OR5:%.*]] = or i1 [[A]], [[B5]]
+; CHECK-NEXT:    [[OR6:%.*]] = or i1 [[A]], [[B6]]
+; CHECK-NEXT:    [[OR7:%.*]] = or i1 [[A]], [[B7]]
+; CHECK-NEXT:    [[XOR0:%.*]] = xor i1 [[OR0]], [[OR1]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i1 [[OR2]], [[OR3]]
+; CHECK-NEXT:    [[XOR2:%.*]] = xor i1 [[OR4]], [[OR5]]
+; CHECK-NEXT:    [[XOR3:%.*]] = xor i1 [[OR6]], [[OR7]]
+; CHECK-NEXT:    [[OR01:%.*]] = xor i1 [[XOR0]], [[XOR1]]
+; CHECK-NEXT:    [[OR23:%.*]] = xor i1 [[XOR2]], [[XOR3]]
+; CHECK-NEXT:    [[OR0123:%.*]] = xor i1 [[OR01]], [[OR23]]
+; CHECK-NEXT:    ret i1 [[OR0123]]
+;
+  %or0 = or i1 %b0, %a
+  %or1 = or i1 %b1, %a
+  %or2 = or i1 %b2, %a
+  %or3 = or i1 %b3, %a
+  %or4 = or i1 %b4, %a
+  %or5 = or i1 %b5, %a
+  %or6 = or i1 %b6, %a
+  %or7 = or i1 %b7, %a
+  %xor0 = xor i1 %or0, %or1
+  %xor1 = xor i1 %or2, %or3
+  %xor2 = xor i1 %or4, %or5
+  %xor3 = xor i1 %or6, %or7
+  %or01 = xor i1 %xor0, %xor1
+  %or23 = xor i1 %xor2, %xor3
+  %or0123 = xor i1 %or01, %or23
+  ret i1 %or0123
+}
+
+define i1 @scalar3(i1 %a, i1 %b0, i1 %b1, i1 %b2, i1 %b3, i1 %b4, i1 %b5, i1 %b6, i1 %b7) local_unnamed_addr {
+; CHECK-LABEL: define i1 @scalar3(
+; CHECK-SAME: i1 [[A:%.*]], i1 [[B0:%.*]], i1 [[B1:%.*]], i1 [[B2:%.*]], i1 [[B3:%.*]], i1 [[B4:%.*]], i1 [[B5:%.*]], i1 [[B6:%.*]], i1 [[B7:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[XOR0:%.*]] = xor i1 [[A]], [[B0]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i1 [[A]], [[B1]]
+; CHECK-NEXT:    [[XOR2:%.*]] = xor i1 [[A]], [[B2]]
+; CHECK-NEXT:    [[XOR3:%.*]] = xor i1 [[A]], [[B3]]
+; CHECK-NEXT:    [[XOR4:%.*]] = xor i1 [[A]], [[B4]]
+; CHECK-NEXT:    [[XOR5:%.*]] = xor i1 [[A]], [[B5]]
+; CHECK-NEXT:    [[XOR6:%.*]] = xor i1 [[A]], [[B6]]
+; CHECK-NEXT:    [[XOR7:%.*]] = xor i1 [[A]], [[B7]]
+; CHECK-NEXT:    [[AND0:%.*]] = and i1 [[XOR0]], [[XOR1]]
+; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[XOR2]], [[XOR3]]
+; CHECK-NEXT:    [[AND2:%.*]] = and i1 [[XOR4]], [[XOR5]]
+; CHECK-NEXT:    [[AND3:%.*]] = and i1 [[XOR6]], [[XOR7]]
+; CHECK-NEXT:    [[OR01:%.*]] = and i1 [[AND0]], [[AND1]]
+; CHECK-NEXT:    [[OR23:%.*]] = and i1 [[AND2]], [[AND3]]
+; CHECK-NEXT:    [[OR0123:%.*]] = and i1 [[OR01]], [[OR23]]
+; CHECK-NEXT:    ret i1 [[OR0123]]
+;
+  %xor0 = xor i1 %b0, %a
+  %xor1 = xor i1 %b1, %a
+  %xor2 = xor i1 %b2, %a
+  %xor3 = xor i1 %b3, %a
+  %xor4 = xor i1 %b4, %a
+  %xor5 = xor i1 %b5, %a
+  %xor6 = xor i1 %b6, %a
+  %xor7 = xor i1 %b7, %a
+  %and0 = and i1 %xor0, %xor1
+  %and1 = and i1 %xor2, %xor3
+  %and2 = and i1 %xor4, %xor5
+  %and3 = and i1 %xor6, %xor7
+  %or01 = and i1 %and0, %and1
+  %or23 = and i1 %and2, %and3
+  %or0123 = and i1 %or01, %or23
+  ret i1 %or0123
+}
+
+define i1 @scalar4(i1 %a, i1 %b0, i1 %b1, i1 %b2, i1 %b3, i1 %b4, i1 %b5, i1 %b6, i1 %b7) local_unnamed_addr {
+; CHECK-LABEL: define i1 @scalar4(
+; CHECK-SAME: i1 [[A:%.*]], i1 [[B0:%.*]], i1 [[B1:%.*]], i1 [[B2:%.*]], i1 [[B3:%.*]], i1 [[B4:%.*]], i1 [[B5:%.*]], i1 [[B6:%.*]], i1 [[B7:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[XOR0:%.*]] = xor i1 [[A]], [[B0]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor i1 [[A]], [[B1]]
+; CHECK-NEXT:    [[XOR2:%.*]] = xor i1 [[A]], [[B2]]
+; CHECK-NEXT:    [[XOR3:%.*]] = xor i1 [[A]], [[B3]]
+; CHECK-NEXT:    [[XOR4:%.*]] = xor i1 [[A]], [[B4]]
+; CHECK-NEXT:    [[XOR5:%.*]] = xor i1 [[A]], [[B5]]
+; CHECK-NEXT:    [[XOR6:%.*]] = xor i1 [[A]], [[B6]]
+; CHECK-NEXT:    [[XOR7:%.*]] = xor i1 [[A]], [[B7]]
+; CHECK-NEXT:    [[OR0:%.*]] = or i1 [[XOR0]], [[XOR1]]
+; CHECK-NEXT:    [[OR1:%.*]] = or i1 [[XOR2]], [[XOR3]]
+; CHECK-NEXT:    [[OR2:%.*]] = or i1 [[XOR4]], [[XOR5]]
+; CHECK-NEXT:    [[OR3:%.*]] = or i1 [[XOR6]], [[XOR7]]
+; CHECK-NEXT:    [[OR4:%.*]] = or i1 [[B0]], [[B1]]
+; CHECK-NEXT:    [[OR5:%.*]] = or i1 [[B2]], [[B3]]
+; CHECK-NEXT:    [[OR6:%.*]] = or i1 [[B4]], [[B5]]
+; CHECK-NEXT:    [[OR7:%.*]] = or i1 [[B6]], [[B7]]
+; CHECK-NEXT:    [[OR01:%.*]] = or i1 [[OR0]], [[OR1]]
+; CHECK-NEXT:    [[OR23:%.*]] = or i1 [[OR2]], [[OR3]]
+; CHECK-NEXT:    [[OR45:%.*]] = or i1 [[OR4]], [[OR5]]
+; CHECK-NEXT:    [[OR67:%.*]] = or i1 [[OR6]], [[OR7]]
+; CHECK-NEXT:    [[OR0123:%.*]] = or i1 [[OR01]], [[OR23]]
+; CHECK-NEXT:    [[OR4567:%.*]] = or i1 [[OR45]], [[OR67]]
+; CHECK-NEXT:    [[OR01234567:%.*]] = or i1 [[OR4567]], [[OR0123]]
+; CHECK-NEXT:    ret i1 [[OR01234567]]
+;
+  %xor0 = xor i1 %b0, %a
+  %xor1 = xor i1 %b1, %a
+  %xor2 = xor i1 %b2, %a
+  %xor3 = xor i1 %b3, %a
+  %xor4 = xor i1 %b4, %a
+  %xor5 = xor i1 %b5, %a
+  %xor6 = xor i1 %b6, %a
+  %xor7 = xor i1 %b7, %a
+  %or0 = or i1 %xor0, %xor1
+  %or1 = or i1 %xor2, %xor3
+  %or2 = or i1 %xor4, %xor5
+  %or3 = or i1 %xor6, %xor7
+  %or4 = or i1 %b0, %b1
+  %or5 = or i1 %b2, %b3
+  %or6 = or i1 %b4, %b5
+  %or7 = or i1 %b6, %b7
+  %or01 = or i1 %or0, %or1
+  %or23 = or i1 %or2, %or3
+  %or45 = or i1 %or4, %or5
+  %or67 = or i1 %or6, %or7
+  %or0123 = or i1 %or01, %or23
+  %or4567 = or i1 %or45, %or67
+  %or01234567 = or i1 %or0123, %or4567
+  ret i1 %or01234567
+}
diff --git a/llvm/test/Transforms/Reassociate/reassoc_bool_vec.ll b/llvm/test/Transforms/Reassociate/reassoc_bool_vec.ll
new file mode 100644
index 00000000000000..289a9181af4014
--- /dev/null
+++ b/llvm/test/Transforms/Reassociate/reassoc_bool_vec.ll
@@ -0,0 +1,281 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -passes=reassociate -S | FileCheck %s
+
+define <8 x i1> @vector0(<8 x i32> %a, <8 x i32> %b0, <8 x i32> %b1, <8 x i32> %b2, <8 x i32> %b3, <8 x i32> %b4, <8 x i32> %b5, <8 x i32> %b6, <8 x i32> %b7) local_unnamed_addr {
+; CHECK-LABEL: define <8 x i1> @vector0(
+; CHECK-SAME: <8 x i32> [[A:%.*]], <8 x i32> [[B0:%.*]], <8 x i32> [[B1:%.*]], <8 x i32> [[B2:%.*]], <8 x i32> [[B3:%.*]], <8 x i32> [[B4:%.*]], <8 x i32> [[B5:%.*]], <8 x i32> [[B6:%.*]], <8 x i32> [[B7:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq <8 x i32> [[B0]], [[A]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq <8 x i32> [[B1]], [[A]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq <8 x i32> [[B2]], [[A]]
+; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq <8 x i32> [[B3]], [[A]]
+; CHECK-NEXT:    [[CMP4:%.*]] = icmp eq <8 x i32> [[B4]], [[A]]
+; CHECK-NEXT:    [[CMP5:%.*]] = icmp eq <8 x i32> [[B5]], [[A]]
+; CHECK-NEXT:    [[CMP6:%.*]] = icmp eq <8 x i32> [[B6]], [[A]]
+; CHECK-NEXT:    [[CMP7:%.*]] = icmp eq <8 x i32> [[B7]], [[A]]
+; CHECK-NEXT:    [[OR67:%.*]] = or <8 x i1> [[CMP1]], [[CMP0]]
+; CHECK-NEXT:    [[OR45:%.*]] = or <8 x i1> [[OR67]], [[CMP2]]
+; CHECK-NEXT:    [[OR4567:%.*]] = or <8 x i1> [[OR45]], [[CMP3]]
+; CHECK-NEXT:    [[OR23:%.*]] = or <8 x i1> [[OR4567]], [[CMP4]]
+; CHECK-NEXT:    [[OR01:%.*]] = or <8 x i1> [[OR23]], [[CMP5]]
+; CHECK-NEXT:    [[OR0123:%.*]] = or <8 x i1> [[OR01]], [[CMP6]]
+; CHECK-NEXT:    [[OR01234567:%.*]] = or <8 x i1> [[OR0123]], [[CMP7]]
+; CHECK-NEXT:    ret <8 x i1> [[OR01234567]]
+;
+  %cmp0 = icmp eq <8 x i32> %b0, %a
+  %cmp1 = icmp eq <8 x i32> %b1, %a
+  %cmp2 = icmp eq <8 x i32> %b2, %a
+  %cmp3 = icmp eq <8 x i32> %b3, %a
+  %cmp4 = icmp eq <8 x i32> %b4, %a
+  %cmp5 = icmp eq <8 x i32> %b5, %a
+  %cmp6 = icmp eq <8 x i32> %b6, %a
+  %cmp7 = icmp eq <8 x i32> %b7, %a
+  %or01 = or <8 x i1> %cmp0, %cmp1
+  %or23 = or <8 x i1> %cmp2, %cmp3
+  %or45 = or <8 x i1> %cmp4, %cmp5
+  %or67 = or <8 x i1> %cmp6, %cmp7
+  %or0123 = or <8 x i1> %or01, %or23
+  %or4567 = or <8 x i1> %or45, %or67
+  %or01234567 = or <8 x i1> %or0123, %or4567
+  ret <8 x i1> %or01234567
+}
+
+define <8 x i1> @vector1(<8 x i32> %a, <8 x i32> %b0, <8 x i32> %b1, <8 x i32> %b2, <8 x i32> %b3, <8 x i32> %b4, <8 x i32> %b5, <8 x i32> %b6, <8 x i32> %b7) local_unnamed_addr {
+; CHECK-LABEL: define <8 x i1> @vector1(
+; CHECK-SAME: <8 x i32> [[A:%.*]], <8 x i32> [[B0:%.*]], <8 x i32> [[B1:%.*]], <8 x i32> [[B2:%.*]], <8 x i32> [[B3:%.*]], <8 x i32> [[B4:%.*]], <8 x i32> [[B5:%.*]], <8 x i32> [[B6:%.*]], <8 x i32> [[B7:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq <8 x i32> [[B0]], [[A]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq <8 x i32> [[B1]], [[A]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq <8 x i32> [[B2]], [[A]]
+; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq <8 x i32> [[B3]], [[A]]
+; CHECK-NEXT:    [[CMP4:%.*]] = icmp eq <8 x i32> [[B4]], [[A]]
+; CHECK-NEXT:    [[CMP5:%.*]] = icmp eq <8 x i32> [[B5]], [[A]]
+; CHECK-NEXT:    [[CMP6:%.*]] = icmp eq <8 x i32> [[B6]], [[A]]
+; CHECK-NEXT:    [[CMP7:%.*]] = icmp eq <8 x i32> [[B7]], [[A]]
+; CHECK-NEXT:    [[OR67:%.*]] = and <8 x i1> [[CMP1]], [[CMP0]]
+; CHECK-NEXT:    [[OR45:%.*]] = and <8 x i1> [[OR67]], [[CMP2]]
+; CHECK-NEXT:    [[OR4567:%.*]] = and <8 x i1> [[OR45]], [[CMP3]]
+; CHECK-NEXT:    [[OR23:%.*]] = and <8 x i1> [[OR4567]], [[CMP4]]
+; CHECK-NEXT:    [[OR01:%.*]] = and <8 x i1> [[OR23]], [[CMP5]]
+; CHECK-NEXT:    [[OR0123:%.*]] = and <8 x i1> [[OR01]], [[CMP6]]
+; CHECK-NEXT:    [[OR01234567:%.*]] = and <8 x i1> [[OR0123]], [[CMP7]]
+; CHECK-NEXT:    ret <8 x i1> [[OR01234567]]
+;
+  %cmp0 = icmp eq <8 x i32> %b0, %a
+  %cmp1 = icmp eq <8 x i32> %b1, %a
+  %cmp2 = icmp eq <8 x i32> %b2, %a
+  %cmp3 = icmp eq <8 x i32> %b3, %a
+  %cmp4 = icmp eq <8 x i32> %b4, %a
+  %cmp5 = icmp eq <8 x i32> %b5, %a
+  %cmp6 = icmp eq <8 x i32> %b6, %a
+  %cmp7 = icmp eq <8 x i32> %b7, %a
+  %or01 = and <8 x i1> %cmp0, %cmp1
+  %or23 = and <8 x i1> %cmp2, %cmp3
+  %or45 = and <8 x i1> %cmp4, %cmp5
+  %or67 = and <8 x i1> %cmp6, %cmp7
+  %or0123 = and <8 x i1> %or01, %or23
+  %or4567 = and <8 x i1> %or45, %or67
+  %or01234567 = and <8 x i1> %or0123, %or4567
+  ret <8 x i1> %or01234567
+}
+
+define <8 x i1> @vector2(<8 x i32> %a, <8 x i32> %b0, <8 x i32> %b1, <8 x i32> %b2, <8 x i32> %b3, <8 x i32> %b4, <8 x i32> %b5, <8 x i32> %b6, <8 x i32> %b7) {
+; CHECK-LABEL: define <8 x i1> @vector2(
+; CHECK-SAME: <8 x i32> [[A:%.*]], <8 x i32> [[B0:%.*]], <8 x i32> [[B1:%.*]], <8 x i32> [[B2:%.*]], <8 x i32> [[B3:%.*]], <8 x i32> [[B4:%.*]], <8 x i32> [[B5:%.*]], <8 x i32> [[B6:%.*]], <8 x i32> [[B7:%.*]]) {
+; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq <8 x i32> [[B0]], [[B1]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq <8 x i32> [[B2]], [[B3]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq <8 x i32> [[B4]], [[B5]]
+; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq <8 x i32> [[B6]], [[B7]]
+; CHECK-NEXT:    [[OR23:%.*]] = and <8 x i1> [[CMP1]], [[CMP0]]
+; CHECK-NEXT:    [[OR01:%.*]] = and <8 x i1> [[OR23]], [[CMP2]]
+; CHECK-NEXT:    [[OR0123:%.*]] = and <8 x i1> [[OR01]], [[CMP3]]
+; CHECK-NEXT:    ret <8 x i1> [[OR0123]]
+;
+  %cmp0 = icmp eq <8 x i32> %b0, %b1
+  %cmp1 = icmp eq <8 x i32> %b2, %b3
+  %cmp2 = icmp eq <8 x i32> %b4, %b5
+  %cmp3 = icmp eq <8 x i32> %b6, %b7
+  %or01 = and <8 x i1> %cmp0, %cmp1
+  %or23 = and <8 x i1> %cmp2, %cmp3
+  %or0123 = and <8 x i1> %or01, %or23
+  ret <8 x i1> %or0123
+}
+
+define <8 x i1> @vector3(<8 x i1> %a, <8 x i1> %b0, <8 x i1> %b1, <8 x i1> %b2, <8 x i1> %b3, <8 x i1> %b4, <8 x i1> %b5, <8 x i1> %b6, <8 x i1> %b7) local_unnamed_addr {
+; CHECK-LABEL: define <8 x i1> @vector3(
+; CHECK-SAME: <8 x i1> [[A:%.*]], <8 x i1> [[B0:%.*]], <8 x i1> [[B1:%.*]], <8 x i1> [[B2:%.*]], <8 x i1> [[B3:%.*]], <8 x i1> [[B4:%.*]], <8 x i1> [[B5:%.*]], <8 x i1> [[B6:%.*]], <8 x i1> [[B7:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[OR0:%.*]] = or <8 x i1> [[B0]], [[A]]
+; CHECK-NEXT:    [[OR1:%.*]] = or <8 x i1> [[B1]], [[A]]
+; CHECK-NEXT:    [[OR2:%.*]] = or <8 x i1> [[B2]], [[A]]
+; CHECK-NEXT:    [[OR3:%.*]] = or <8 x i1> [[B3]], [[A]]
+; CHECK-NEXT:    [[OR4:%.*]] = or <8 x i1> [[B4]], [[A]]
+; CHECK-NEXT:    [[OR5:%.*]] = or <8 x i1> [[B5]], [[A]]
+; CHECK-NEXT:    [[OR6:%.*]] = or <8 x i1> [[B6]], [[A]]
+; CHECK-NEXT:    [[OR7:%.*]] = or <8 x i1> [[B7]], [[A]]
+; CHECK-NEXT:    [[XOR3:%.*]] = xor <8 x i1> [[OR1]], [[OR0]]
+; CHECK-NEXT:    [[XOR2:%.*]] = xor <8 x i1> [[XOR3]], [[OR2]]
+; CHECK-NEXT:    [[XOR7:%.*]] = xor <8 x i1> [[XOR2]], [[OR3]]
+; CHECK-NEXT:    [[XOR0:%.*]] = xor <8 x i1> [[XOR7]], [[OR4]]
+; CHECK-NEXT:    [[XOR4:%.*]] = xor <8 x i1> [[XOR0]], [[OR5]]
+; CHECK-NEXT:    [[XOR5:%.*]] = xor <8 x i1> [[XOR4]], [[OR6]]
+; CHECK-NEXT:    [[OR4560:%.*]] = xor <8 x i1> [[XOR5]], [[OR7]]
+; CHECK-NEXT:    [[OR023:%.*]] = or <8 x i1> [[XOR2]], [[XOR3]]
+; CHECK-NEXT:    [[XOR6:%.*]] = or <8 x i1> [[OR023]], [[XOR7]]
+; CHECK-NEXT:    [[OR060:%.*]] = or <8 x i1> [[XOR6]], [[XOR0]]
+; CHECK-NEXT:    [[OR001:%.*]] = or <8 x i1> [[OR060]], [[XOR4]]
+; CHECK-NEXT:    [[OR0123:%.*]] = or <8 x i1> [[OR001]], [[XOR5]]
+; CHECK-NEXT:    [[OR01234567:%.*]] = or <8 x i1> [[OR0123]], [[OR4560]]
+; CHECK-NEXT:    ret <8 x i1> [[OR01234567]]
+;
+  %or0 = or <8 x i1> %b0, %a
+  %or1 = or <8 x i1> %b1, %a
+  %or2 = or <8 x i1> %b2, %a
+  %or3 = or <8 x i1> %b3, %a
+  %or4 = or <8 x i1> %b4, %a
+  %or5 = or <8 x i1> %b5, %a
+  %or6 = or <8 x i1> %b6, %a
+  %or7 = or <8 x i1> %b7, %a
+  %xor0 = xor <8 x i1> %or0, %or1
+  %xor1 = xor <8 x i1> %xor0, %or2
+  %xor2 = xor <8 x i1> %xor1, %or3
+  %xor3 = xor <8 x i1> %xor2, %or4
+  %xor4 = xor <8 x i1> %xor3, %or5
+  %xor5 = xor <8 x i1> %xor4, %or6
+  %xor6 = xor <8 x i1> %xor5, %or7
+  %or001 = or <8 x i1> %xor0, %xor1
+  %or023 = or <8 x i1> %xor2, %xor3
+  %or045 = or <8 x i1> %xor4, %xor5
+  %or060 = or <8 x i1> %xor6, %xor0
+  %or0123 = or <8 x i1> %or001, %or023
+  %or4560 = or <8 x i1> %or045, %or060
+  %or01234567 = or <8 x i1> %or0123, %or4560
+  ret <8 x i1> %or01234567
+}
+
+define <8 x i1> @vector4(<8 x i1> %a, <8 x i1> %b0, <8 x i1> %b1, <8 x i1> %b2, <8 x i1> %b3, <8 x i1> %b4, <8 x i1> %b5, <8 x i1> %b6, <8 x i1> %b7) local_unnamed_addr {
+; CHECK-LABEL: define <8 x i1> @vector4(
+; CHECK-SAME: <8 x i1> [[A:%.*]], <8 x i1> [[B0:%.*]], <8 x i1> [[B1:%.*]], <8 x i1> [[B2:%.*]], <8 x i1> [[B3:%.*]], <8 x i1> [[B4:%.*]], <8 x i1> [[B5:%.*]], <8 x i1> [[B6:%.*]], <8 x i1> [[B7:%.*]]) local_unnamed_addr {
+; CHECK-NEXT:    [[OR0:%.*]] = or <8 x i1> [[B0]], [[A]]
+; CHECK-NEXT:    [[OR1:%.*]] = or <8 x i1> [[B1]], [[A]]
+; CHECK-NEXT:    [[OR2:%.*]] = or <8 x i1> [[B2]], [[A]]
+; CHECK-NEXT:    [[OR3:%.*]] = or <8 x i1> [[B3]], [[A]]
+; CHECK-NEXT:    [[OR4:%.*]] = or <8 x i1> [[B4]], [[A]]
+; CHECK-NEXT:    [[OR5:%.*]] = or <8 x i1> [[B5]], [[A]]
+; CHECK-NEXT:    [[OR6:%.*]] = or <8 x i1> [[B6]], [[A]]
+; CHECK-NEXT:    [[OR7:%.*]] = or <8 x i1> [[B7]], [[A]]
+; CHECK-NEXT:    [[XOR3:%.*]] = xor <8 x i1> [[OR1]], [[OR0]]
+; CHECK-NEXT:    [[XOR2:%.*]] = xor <8 x i1> [[XOR3]], [[OR2]]
+; CHECK-NEXT:    [[OR23:%.*]] = xor <8 x i1> [[XOR2]], [[OR3]]
+; CHECK-NEXT:    [[XOR1:%.*]] = xor <8 x i1> [[OR23]], [[OR4]]
+; CHECK-NEXT:    [[XOR0:%.*]] = xor <8 x i1> [[XOR1]], [[OR5]]
+; CHECK-NEXT:    [[OR01:%.*]] = xor <8 x i1> [[XOR0]], [[OR6]]
+; CHECK-NEXT:    [[OR0123:%.*]] = xor <8 x i1> [[OR01]], [[OR7]]
+; CHECK-NEXT:    ret <8 x i1> [[OR0123]]
+;
+  %or0 = or <8 x i1> %b0, %a
+  %or1 = or <8 x i1> %b1, %a
+  %or2 = or <8 x i1> %b2, %a
+  %or3 = or <8 x i1> %b3, %a
+  %or4 = or <8 x i1> %b4, %a
+  %or5 = or <8 x i1> %b5, %a
+  %or6 = or <8 x i1> %b6, %a
+  %or7 = or <8 x i1> %b7, %a
+  %xor0 = xor <8 x i1> %or0, %or1
+  %xor1 = xor <8 x i1> %or2, %or3
+  %xor2 = xor <8 x i1> %or4, %or5
+  %xor3 = xor <8 x i1> %or6, %or7
+  %or01 = xor <8 x i1> %xor0, %xor1
+  %or23 = xor <8 x i1> %xor2, %xor3
+  %or0123 = xor <8 x i1> %or01, %or23
+  ret <8 x i1> %or0123
+}
+
+define <8 x i1> @vector5(<8 x i1> %a, <8 x i1> %b0, <8 x i1> %b1, <8 x i1> %b2, <8 x i1> %b3, <8 x i1> %b4, <8 x i1> %b...
[truncated]

; CHECK-NEXT: [[OR01234567:%.*]] = or i1 [[OR0123]], [[OR4567]]
; CHECK-NEXT: ret i1 [[OR01234567]]
;
%cmp0 = icmp eq i32 %b0, %a
Copy link
Member

Choose a reason for hiding this comment

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

I don't think the instruction kind of %cmpx matters. It would be better to make them parameters.
See https://godbolt.org/z/5Kfdx6fjn

@nikic
Copy link
Contributor

nikic commented May 3, 2024

Resolve #64840

I'm a bit confused here, this seems to be just test coverage, not a fix for that issue? The vector tests seem to still show the linearization behavior if I'm understanding things correctly.

@nikic nikic changed the title Adds test coverage for reassociation of scalar & vector boolean types [Reassociate] Adds test coverage for reassociation of scalar & vector boolean types May 3, 2024
@RKSimon
Copy link
Collaborator

RKSimon commented May 3, 2024

This is just the first step for #64840 - the actual change to vector bools (+ perf testing) are still to follow

@SahilPatidar
Copy link
Contributor Author

@RKSimon Assuming this is all good to go, what's the next step?

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM, though I would put the scalar and vector tests in one file.

llvm/test/Transforms/Reassociate/reassoc_bool.ll Outdated Show resolved Hide resolved
@nikic nikic merged commit aac83fc into llvm:main May 7, 2024
3 of 4 checks passed
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.

None yet

5 participants