[llvm] [BDCE] Handle multi-use `and`/`or` on demanded bits (PR #79688)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 28 00:41:08 PST 2024


================
@@ -0,0 +1,204 @@
+; 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:    [[RET1:%.*]] = and i64 [[A]], 8
+; CHECK-NEXT:    [[RET2:%.*]] = and i64 [[A]], 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 @and(i64 %a) {
+; CHECK-LABEL: define void @and(
+; CHECK-SAME: i64 [[A:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[RET1:%.*]] = and i64 [[A]], 8
+; CHECK-NEXT:    [[RET2:%.*]] = and i64 [[A]], 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:    [[OR:%.*]] = or i64 [[A]], [[B]]
+; 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
----------------
nikic wrote:

Can you please add a test variant with `or disjoint`, to show that the flag gets dropped correctly?

https://github.com/llvm/llvm-project/pull/79688


More information about the llvm-commits mailing list