[llvm] 0a15ead - [BDCE] Introduce test for PR79688 (NFC)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 29 10:07:45 PST 2024
Author: Antonio Frighetto
Date: 2024-01-29T19:03:24+01:00
New Revision: 0a15ead01b6be095a87a405e63e9525ed123ac58
URL: https://github.com/llvm/llvm-project/commit/0a15ead01b6be095a87a405e63e9525ed123ac58
DIFF: https://github.com/llvm/llvm-project/commit/0a15ead01b6be095a87a405e63e9525ed123ac58.diff
LOG: [BDCE] Introduce test for PR79688 (NFC)
Added:
llvm/test/Transforms/BDCE/binops-multiuse.ll
Modified:
Removed:
################################################################################
diff --git a/llvm/test/Transforms/BDCE/binops-multiuse.ll b/llvm/test/Transforms/BDCE/binops-multiuse.ll
new file mode 100644
index 000000000000000..bf1993bce2de74c
--- /dev/null
+++ b/llvm/test/Transforms/BDCE/binops-multiuse.ll
@@ -0,0 +1,282 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -S -passes=bdce < %s | FileCheck %s
+
+define void @or(i64 %a) {
+; CHECK-LABEL: define void @or(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], 3
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[OR]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[OR]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %or = or i64 %a, 3 ; Mask: 0000 0011
+ %ret1 = and i64 %or, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %or, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @xor(i64 %a) {
+; CHECK-LABEL: define void @xor(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[A]], 3
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[XOR]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[XOR]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %xor = xor i64 %a, 3 ; Mask: 0000 0011
+ %ret1 = and i64 %xor, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %xor, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @and(i64 %a) {
+; CHECK-LABEL: define void @and(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND:%.*]] = and i64 [[A]], 24
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[AND]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[AND]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %and = and i64 %a, 24 ; Mask: 0001 1000
+ %ret1 = and i64 %and, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %and, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @or_of_and(i64 %a, i64 %b) {
+; CHECK-LABEL: define void @or_of_and(
+; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and i64 [[A]], 24
+; CHECK-NEXT: [[AND2:%.*]] = and i64 [[B]], 25
+; CHECK-NEXT: [[OR:%.*]] = or i64 [[AND1]], [[AND2]]
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[OR]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[OR]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %and1 = and i64 %a, 24 ; Mask: 0001 1000
+ %and2 = and i64 %b, 25 ; Mask: 0001 1001
+ %or = or i64 %and1, %and2
+ %ret1 = and i64 %or, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %or, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @or_disjoint_of_and(i64 %a, i64 %b) {
+; CHECK-LABEL: define void @or_disjoint_of_and(
+; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and i64 [[A]], 56
+; CHECK-NEXT: [[AND2:%.*]] = and i64 [[B]], 25
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i64 [[AND1]], [[AND2]]
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[OR]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[OR]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %and1 = and i64 %a, 56 ; Mask: 0011 1000
+ %and2 = and i64 %b, 25 ; Mask: 0001 1001
+ %or = or disjoint i64 %and1, %and2
+ %ret1 = and i64 %or, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %or, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @select_of_and(i1 %c, i64 %a, i64 %b) {
+; CHECK-LABEL: define void @select_of_and(
+; CHECK-SAME: i1 [[C:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and i64 [[A]], 24
+; CHECK-NEXT: [[AND2:%.*]] = and i64 [[B]], 25
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i64 [[AND1]], i64 [[AND2]]
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[S]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[S]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %and1 = and i64 %a, 24 ; Mask: 0001 1000
+ %and2 = and i64 %b, 25 ; Mask: 0001 1001
+ %s = select i1 %c, i64 %and1, i64 %and2
+ %ret1 = and i64 %s, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %s, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @select_of_and_2(i1 %c, i64 %a, i64 %b) {
+; CHECK-LABEL: define void @select_of_and_2(
+; CHECK-SAME: i1 [[C:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and i64 [[A]], 25
+; CHECK-NEXT: [[AND2:%.*]] = and i64 [[B]], 23
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i64 [[AND1]], i64 [[AND2]]
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[S]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[S]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %and1 = and i64 %a, 25 ; Mask: 0001 1001
+ %and2 = and i64 %b, 23 ; Mask: 0001 0111
+ %s = select i1 %c, i64 %and1, i64 %and2
+ %ret1 = and i64 %s, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %s, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @select_of_and_multiuse(i1 %c, i64 %a, i64 %b) {
+; CHECK-LABEL: define void @select_of_and_multiuse(
+; CHECK-SAME: i1 [[C:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and i64 [[A]], 24
+; CHECK-NEXT: [[AND2:%.*]] = and i64 [[B]], 25
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i64 [[AND1]], i64 [[AND2]]
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[S]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[S]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use2(i64 [[RET2]], i64 [[AND2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %and1 = and i64 %a, 24 ; Mask: 0001 1000
+ %and2 = and i64 %b, 25 ; Mask: 0001 1001
+ %s = select i1 %c, i64 %and1, i64 %and2
+ %ret1 = and i64 %s, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %s, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use2(i64 %ret2, i64 %and2)
+ ret void
+}
+
+define void @select_of_and_
diff erent_demanded(i1 %c, i64 %a, i64 %b) {
+; CHECK-LABEL: define void @select_of_and_
diff erent_demanded(
+; CHECK-SAME: i1 [[C:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and i64 0, 24
+; CHECK-NEXT: [[AND2:%.*]] = and i64 [[B]], 25
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i64 [[AND1]], i64 [[AND2]]
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[S]], 3
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[S]], 7
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %and1 = and i64 %a, 24 ; Mask: 0001 1000
+ %and2 = and i64 %b, 25 ; Mask: 0001 1001
+ %s = select i1 %c, i64 %and1, i64 %and2
+ %ret1 = and i64 %s, 3 ; Demanded bits: 0000 0011
+ %ret2 = and i64 %s, 7 ; Demanded bits: 0000 0111
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @select_of_or(i1 %c, i64 %a, i64 %b) {
+; CHECK-LABEL: define void @select_of_or(
+; CHECK-SAME: i1 [[C:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[OR1:%.*]] = or i64 [[A]], 3
+; CHECK-NEXT: [[OR2:%.*]] = or i64 [[B]], 192
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i64 [[OR1]], i64 [[OR2]]
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[S]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[S]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %or1 = or i64 %a, 3 ; Mask: 0000 0011
+ %or2 = or i64 %b, 192 ; Mask: 1100 0000
+ %s = select i1 %c, i64 %or1, i64 %or2
+ %ret1 = and i64 %s, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %s, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @select_of_xor(i1 %c, i64 %a, i64 %b) {
+; CHECK-LABEL: define void @select_of_xor(
+; CHECK-SAME: i1 [[C:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[XOR1:%.*]] = xor i64 [[A]], 128
+; CHECK-NEXT: [[XOR2:%.*]] = xor i64 [[B]], 36
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i64 [[XOR1]], i64 [[XOR2]]
+; CHECK-NEXT: [[RET1:%.*]] = and i64 [[S]], 8
+; CHECK-NEXT: [[RET2:%.*]] = and i64 [[S]], 16
+; CHECK-NEXT: call void @use(i64 [[RET1]])
+; CHECK-NEXT: call void @use(i64 [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %xor1 = xor i64 %a, 128 ; Mask: 1000 0000
+ %xor2 = xor i64 %b, 36 ; Mask: 0010 0100
+ %s = select i1 %c, i64 %xor1, i64 %xor2
+ %ret1 = and i64 %s, 8 ; Demanded bits: 0000 1000
+ %ret2 = and i64 %s, 16 ; Demanded bits: 0001 0000
+ call void @use(i64 %ret1)
+ call void @use(i64 %ret2)
+ ret void
+}
+
+define void @select_vectorized(i1 %c, <2 x i8> %a, <2 x i8> %b) {
+; CHECK-LABEL: define void @select_vectorized(
+; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and <2 x i8> [[A]], <i8 28, i8 28>
+; CHECK-NEXT: [[AND2:%.*]] = and <2 x i8> [[B]], <i8 29, i8 29>
+; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], <2 x i8> [[AND1]], <2 x i8> [[AND2]]
+; CHECK-NEXT: [[RET1:%.*]] = and <2 x i8> [[S]], <i8 4, i8 4>
+; CHECK-NEXT: [[RET2:%.*]] = and <2 x i8> [[S]], <i8 12, i8 12>
+; CHECK-NEXT: call void @use3(<2 x i8> [[RET1]])
+; CHECK-NEXT: call void @use3(<2 x i8> [[RET2]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %and1 = and <2 x i8> %a, <i8 28, i8 28>
+ %and2 = and <2 x i8> %b, <i8 29, i8 29>
+ %s = select i1 %c, <2 x i8> %and1, <2 x i8> %and2
+ %ret1 = and <2 x i8> %s, <i8 4, i8 4>
+ %ret2 = and <2 x i8> %s, <i8 12, i8 12>
+ call void @use3(<2 x i8> %ret1)
+ call void @use3(<2 x i8> %ret2)
+ ret void
+}
+
+declare void @use(i64)
+declare void @use2(i64, i64)
+declare void @use3(<2 x i8>)
More information about the llvm-commits
mailing list