Files
clang-p2996/llvm/test/Transforms/InstCombine/select-factorize.ll
Yingwei Zheng b23f59a646 [InstCombine] Fold select (A &/| B), T, F if select B, T, F is foldable (#76621)
This patch does the following folds:
```
(select A && B, T, F) -> (select A, (select B, T, F), F)
(select A || B, T, F) -> (select A, T, (select B, T, F))
```
if `(select B, T, F)` can be folded into a value or a canonicalized SPF.
Alive2: https://alive2.llvm.org/ce/z/4Bdrbu

The original motivation of this patch is to simplify the following
pattern:
```
%.sroa.speculated.i = tail call i64 @llvm.umax.i64(i64 %sub.ptr.div.i.i, i64 1)
%add.i = add i64 %.sroa.speculated.i, %sub.ptr.div.i.i
%cmp7.i = icmp ult i64 %add.i, %sub.ptr.div.i.i
%cmp9.i = icmp ugt i64 %add.i, 1152921504606846975
%or.cond.i = or i1 %cmp7.i, %cmp9.i
%cond.i = select i1 %or.cond.i, i64 1152921504606846975, i64 %add.i
->
%.sroa.speculated.i = tail call i64 @llvm.umax.i64(i64 %sub.ptr.div.i.i, i64 1)
%add.i = add i64 %.sroa.speculated.i, %sub.ptr.div.i.i
%cmp7.i = icmp ult i64 %add.i, %sub.ptr.div.i.i
%max = call i64 @llvm.umax.i64(i64 %add.i, 1152921504606846975)
%cond.i = select i1 %cmp7.i, i64 1152921504606846975, i64 %max
```
The later form has a better codegen for some backends. It is also more
analysis-friendly than the original one.
Godbolt: https://godbolt.org/z/eK6eb5jf1
Alive2: https://alive2.llvm.org/ce/z/VHlxL2

Compile-time impact:
http://llvm-compile-time-tracker.com/compare.php?from=7c71d3996a72b9b024622f23bf556539b961c88c&to=638ce8666fadaca1ab2639a3c2bc52a4a8508f40&stat=instructions:u

|stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang|
|--|--|--|--|--|--|--|
|+0.02%|-0.00%|+0.02%|-0.03%|-0.00%|-0.05%|-0.00%|

It is an alternative to #76203 and #76363 because we can simplify
`select (icmp eq/ne a, b), a, b` into `b` or `a`.
Fixes #75784.
Fixes #76043.

Thank @XChy for providing additional tests.
Co-authored-by: XChy <xxs_chy@outlook.com>
2023-12-31 18:28:48 +08:00

761 lines
28 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=instcombine -S < %s | FileCheck %s
declare void @use(i1)
define i1 @logic_and_logic_or_1(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_and_logic_or_1(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 %a, i1 false
%bc = select i1 %c, i1 %b, i1 false
%or = select i1 %ac, i1 true, i1 %bc
ret i1 %or
}
define i1 @logic_and_logic_or_2(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_and_logic_or_2(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %a, i1 %c, i1 false
%bc = select i1 %c, i1 %b, i1 false
%or = select i1 %ac, i1 true, i1 %bc
ret i1 %or
}
define i1 @logic_and_logic_or_3(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_and_logic_or_3(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i1 [[C:%.*]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %a, i1 %c, i1 false
%bc = select i1 %b, i1 %c, i1 false
%or = select i1 %ac, i1 true, i1 %bc
ret i1 %or
}
define i1 @logic_and_logic_or_4(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_and_logic_or_4(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 %a, i1 false
%bc = select i1 %b, i1 %c, i1 false
%or = select i1 %ac, i1 true, i1 %bc
ret i1 %or
}
define i1 @logic_and_logic_or_5(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_and_logic_or_5(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 %a, i1 false
%bc = select i1 %c, i1 %b, i1 false
%or = select i1 %bc, i1 true, i1 %ac
ret i1 %or
}
define i1 @logic_and_logic_or_6(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_and_logic_or_6(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %a, i1 %c, i1 false
%bc = select i1 %c, i1 %b, i1 false
%or = select i1 %bc, i1 true, i1 %ac
ret i1 %or
}
define i1 @logic_and_logic_or_7(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_and_logic_or_7(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i1 [[C:%.*]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %a, i1 %c, i1 false
%bc = select i1 %b, i1 %c, i1 false
%or = select i1 %bc, i1 true, i1 %ac
ret i1 %or
}
define i1 @logic_and_logic_or_8(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_and_logic_or_8(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 %a, i1 false
%bc = select i1 %b, i1 %c, i1 false
%or = select i1 %bc, i1 true, i1 %ac
ret i1 %or
}
define <3 x i1> @logic_and_logic_or_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @logic_and_logic_or_vector(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[TMP1]], <3 x i1> zeroinitializer
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = select <3 x i1> %c, <3 x i1> %a, <3 x i1> <i1 false, i1 false, i1 false>
%bc = select <3 x i1> %c, <3 x i1> %b, <3 x i1> <i1 false, i1 false, i1 false>
%or = select <3 x i1> %ac, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %bc
ret <3 x i1> %or
}
define <3 x i1> @logic_and_logic_or_vector_poison1(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @logic_and_logic_or_vector_poison1(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[TMP1]], <3 x i1> zeroinitializer
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = select <3 x i1> %c, <3 x i1> %a, <3 x i1> <i1 false, i1 false, i1 false>
%bc = select <3 x i1> %c, <3 x i1> %b, <3 x i1> <i1 false, i1 false, i1 false>
%or = select <3 x i1> %ac, <3 x i1> <i1 true, i1 true, i1 poison>, <3 x i1> %bc
ret <3 x i1> %or
}
define <3 x i1> @logic_and_logic_or_vector_poison2(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @logic_and_logic_or_vector_poison2(
; CHECK-NEXT: [[AC:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[A:%.*]], <3 x i1> <i1 false, i1 poison, i1 false>
; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[BC]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = select <3 x i1> %c, <3 x i1> %a, <3 x i1> <i1 false, i1 poison, i1 false>
%bc = select <3 x i1> %c, <3 x i1> %b, <3 x i1> <i1 false, i1 false, i1 false>
%or = select <3 x i1> %ac, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %bc
ret <3 x i1> %or
}
define <3 x i1> @logic_and_logic_or_vector_poison3(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @logic_and_logic_or_vector_poison3(
; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[BC]], <3 x i1> <i1 poison, i1 false, i1 false>
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = select <3 x i1> %c, <3 x i1> %a, <3 x i1> <i1 false, i1 false, i1 false>
%bc = select <3 x i1> %c, <3 x i1> %b, <3 x i1> <i1 poison, i1 false, i1 false>
%or = select <3 x i1> %ac, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %bc
ret <3 x i1> %or
}
; negative test: not one use for both op
define i1 @logic_and_logic_or_not_one_use(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_and_logic_or_not_one_use(
; CHECK-NEXT: [[AC:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 true, i1 [[BC]]
; CHECK-NEXT: call void @use(i1 [[AC]])
; CHECK-NEXT: call void @use(i1 [[BC]])
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 %a, i1 false
%bc = select i1 %c, i1 %b, i1 false
%or = select i1 %ac, i1 true, i1 %bc
call void @use(i1 %ac)
call void @use(i1 %bc)
ret i1 %or
}
define i1 @and_logic_and_logic_or_1(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_logic_and_logic_or_1(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %c, %a
%bc = select i1 %c, i1 %b, i1 false
%or = select i1 %ac, i1 true, i1 %bc
ret i1 %or
}
define i1 @and_logic_and_logic_or_2(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_logic_and_logic_or_2(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %c, %a
%bc = select i1 %b, i1 %c, i1 false
%or = select i1 %ac, i1 true, i1 %bc
ret i1 %or
}
define i1 @and_logic_and_logic_or_3(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_logic_and_logic_or_3(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %a, %c
%bc = select i1 %c, i1 %b, i1 false
%or = select i1 %ac, i1 true, i1 %bc
ret i1 %or
}
define i1 @and_logic_and_logic_or_4(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_logic_and_logic_or_4(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %a, %c
%bc = select i1 %b, i1 %c, i1 false
%or = select i1 %ac, i1 true, i1 %bc
ret i1 %or
}
define i1 @and_logic_and_logic_or_5(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_logic_and_logic_or_5(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %c, %a
%bc = select i1 %c, i1 %b, i1 false
%or = select i1 %bc, i1 true, i1 %ac
ret i1 %or
}
define i1 @and_logic_and_logic_or_6(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_logic_and_logic_or_6(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[OR:%.*]] = and i1 [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %c, %a
%bc = select i1 %b, i1 %c, i1 false
%or = select i1 %bc, i1 true, i1 %ac
ret i1 %or
}
define i1 @and_logic_and_logic_or_7(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_logic_and_logic_or_7(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 false
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %a, %c
%bc = select i1 %c, i1 %b, i1 false
%or = select i1 %bc, i1 true, i1 %ac
ret i1 %or
}
define i1 @and_logic_and_logic_or_8(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_logic_and_logic_or_8(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[OR:%.*]] = and i1 [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %a, %c
%bc = select i1 %b, i1 %c, i1 false
%or = select i1 %bc, i1 true, i1 %ac
ret i1 %or
}
define <3 x i1> @and_logic_and_logic_or_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @and_logic_and_logic_or_vector(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[TMP1]], <3 x i1> zeroinitializer
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = and <3 x i1> %c, %a
%bc = select <3 x i1> %c, <3 x i1> %b, <3 x i1> <i1 false, i1 false, i1 false>
%or = select <3 x i1> %ac, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %bc
ret <3 x i1> %or
}
define <3 x i1> @and_logic_and_logic_or_vector_poison1(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @and_logic_and_logic_or_vector_poison1(
; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[BC]], <3 x i1> <i1 false, i1 poison, i1 false>
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = and <3 x i1> %c, %a
%bc = select <3 x i1> %c, <3 x i1> %b, <3 x i1> <i1 false, i1 poison, i1 false>
%or = select <3 x i1> %ac, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %bc
ret <3 x i1> %or
}
define <3 x i1> @and_logic_and_logic_or_vector_poison2(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @and_logic_and_logic_or_vector_poison2(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[TMP1]], <3 x i1> zeroinitializer
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = and <3 x i1> %c, %a
%bc = select <3 x i1> %c, <3 x i1> %b, <3 x i1> <i1 false, i1 false, i1 false>
%or = select <3 x i1> %ac, <3 x i1> <i1 poison, i1 true, i1 true>, <3 x i1> %bc
ret <3 x i1> %or
}
define i1 @and_logic_and_logic_or_not_one_use(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_logic_and_logic_or_not_one_use(
; CHECK-NEXT: [[AC:%.*]] = and i1 [[A:%.*]], [[C:%.*]]
; CHECK-NEXT: [[BC:%.*]] = select i1 [[B:%.*]], i1 [[C]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[B]], i1 [[C]], i1 [[AC]]
; CHECK-NEXT: call void @use(i1 [[AC]])
; CHECK-NEXT: call void @use(i1 [[BC]])
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %a, %c
%bc = select i1 %b, i1 %c, i1 false
%or = select i1 %bc, i1 true, i1 %ac
call void @use(i1 %ac)
call void @use(i1 %bc)
ret i1 %or
}
define i1 @and_and_logic_or_1(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_and_logic_or_1(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = and i1 [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %c, %a
%bc = and i1 %c, %b
%or = select i1 %ac, i1 true, i1 %bc
ret i1 %or
}
define i1 @and_and_logic_or_2(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_and_logic_or_2(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[OR:%.*]] = and i1 [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %a, %c
%bc = and i1 %c, %b
%or = select i1 %bc, i1 true, i1 %ac
ret i1 %or
}
define <3 x i1> @and_and_logic_or_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @and_and_logic_or_vector(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = and <3 x i1> [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = and <3 x i1> %c, %a
%bc = and <3 x i1> %c, %b
%or = select <3 x i1> %ac, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %bc
ret <3 x i1> %or
}
define <3 x i1> @and_and_logic_or_vector_poison(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @and_and_logic_or_vector_poison(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = and <3 x i1> [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = and <3 x i1> %c, %a
%bc = and <3 x i1> %c, %b
%or = select <3 x i1> %ac, <3 x i1> <i1 true, i1 poison, i1 true>, <3 x i1> %bc
ret <3 x i1> %or
}
define i1 @and_and_logic_or_not_one_use(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @and_and_logic_or_not_one_use(
; CHECK-NEXT: [[AC:%.*]] = and i1 [[A:%.*]], [[C:%.*]]
; CHECK-NEXT: [[BC:%.*]] = and i1 [[C]], [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[B]], i1 [[C]], i1 [[AC]]
; CHECK-NEXT: call void @use(i1 [[AC]])
; CHECK-NEXT: call void @use(i1 [[BC]])
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = and i1 %a, %c
%bc = and i1 %c, %b
%or = select i1 %bc, i1 true, i1 %ac
call void @use(i1 %ac)
call void @use(i1 %bc)
ret i1 %or
}
define i1 @logic_or_logic_and_1(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_or_logic_and_1(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 true, i1 %a
%bc = select i1 %c, i1 true, i1 %b
%or = select i1 %ac, i1 %bc, i1 false
ret i1 %or
}
define i1 @logic_or_logic_and_2(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_or_logic_and_2(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %a, i1 true, i1 %c
%bc = select i1 %c, i1 true, i1 %b
%or = select i1 %ac, i1 %bc, i1 false
ret i1 %or
}
define i1 @logic_or_logic_and_3(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_or_logic_and_3(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i1 true, i1 [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %a, i1 true, i1 %c
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %ac, i1 %bc, i1 false
ret i1 %or
}
define i1 @logic_or_logic_and_4(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_or_logic_and_4(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 true, i1 %a
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %ac, i1 %bc, i1 false
ret i1 %or
}
define i1 @logic_or_logic_and_5(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_or_logic_and_5(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 true, i1 %a
%bc = select i1 %c, i1 true, i1 %b
%or = select i1 %bc, i1 %ac, i1 false
ret i1 %or
}
define i1 @logic_or_logic_and_6(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_or_logic_and_6(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %a, i1 true, i1 %c
%bc = select i1 %c, i1 true, i1 %b
%or = select i1 %bc, i1 %ac, i1 false
ret i1 %or
}
define i1 @logic_or_logic_and_7(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_or_logic_and_7(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i1 true, i1 [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %a, i1 true, i1 %c
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %bc, i1 %ac, i1 false
ret i1 %or
}
define i1 @logic_or_logic_and_8(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_or_logic_and_8(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 true, i1 %a
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %bc, i1 %ac, i1 false
ret i1 %or
}
define <3 x i1> @logic_or_logic_and_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @logic_or_logic_and_vector(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[TMP1]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %a
%bc = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %b
%or = select <3 x i1> %ac, <3 x i1> %bc, <3 x i1> <i1 false, i1 false, i1 false>
ret <3 x i1> %or
}
define <3 x i1> @logic_or_logic_and_vector_poison1(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @logic_or_logic_and_vector_poison1(
; CHECK-NEXT: [[AC:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> <i1 poison, i1 true, i1 true>, <3 x i1> [[A:%.*]]
; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[B:%.*]]
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> [[BC]], <3 x i1> zeroinitializer
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = select <3 x i1> %c, <3 x i1> <i1 poison, i1 true, i1 true>, <3 x i1> %a
%bc = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %b
%or = select <3 x i1> %ac, <3 x i1> %bc, <3 x i1> <i1 false, i1 false, i1 false>
ret <3 x i1> %or
}
define <3 x i1> @logic_or_logic_and_vector_poison2(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @logic_or_logic_and_vector_poison2(
; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> <i1 true, i1 poison, i1 true>, <3 x i1> [[BC]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %a
%bc = select <3 x i1> %c, <3 x i1> <i1 true, i1 poison, i1 true>, <3 x i1> %b
%or = select <3 x i1> %ac, <3 x i1> %bc, <3 x i1> <i1 false, i1 false, i1 false>
ret <3 x i1> %or
}
define <3 x i1> @logic_or_logic_and_vector_poison3(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @logic_or_logic_and_vector_poison3(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[TMP1]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %a
%bc = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %b
%or = select <3 x i1> %ac, <3 x i1> %bc, <3 x i1> <i1 false, i1 false, i1 poison>
ret <3 x i1> %or
}
; negative test: not one use for both op
define i1 @logic_or_logic_and_not_one_use(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @logic_or_logic_and_not_one_use(
; CHECK-NEXT: [[AC:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]]
; CHECK-NEXT: [[BC:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[C]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[B]], i1 [[AC]], i1 [[C]]
; CHECK-NEXT: call void @use(i1 [[AC]])
; CHECK-NEXT: call void @use(i1 [[BC]])
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = select i1 %c, i1 true, i1 %a
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %bc, i1 %ac, i1 false
call void @use(i1 %ac)
call void @use(i1 %bc)
ret i1 %or
}
define i1 @or_logic_or_logic_and_1(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_logic_or_logic_and_1(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %c, %a
%bc = select i1 %c, i1 true, i1 %b
%or = select i1 %ac, i1 %bc, i1 false
ret i1 %or
}
define i1 @or_logic_or_logic_and_2(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_logic_or_logic_and_2(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %c, %a
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %ac, i1 %bc, i1 false
ret i1 %or
}
define i1 @or_logic_or_logic_and_3(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_logic_or_logic_and_3(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %c, %a
%bc = select i1 %c, i1 true, i1 %b
%or = select i1 %bc, i1 %ac, i1 false
ret i1 %or
}
define i1 @or_logic_or_logic_and_4(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_logic_or_logic_and_4(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %c, %a
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %bc, i1 %ac, i1 false
ret i1 %or
}
define i1 @or_logic_or_logic_and_5(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_logic_or_logic_and_5(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %a, %c
%bc = select i1 %c, i1 true, i1 %b
%or = select i1 %ac, i1 %bc, i1 false
ret i1 %or
}
define i1 @or_logic_or_logic_and_6(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_logic_or_logic_and_6(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %a, %c
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %ac, i1 %bc, i1 false
ret i1 %or
}
define i1 @or_logic_or_logic_and_7(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_logic_or_logic_and_7(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[TMP1]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %a, %c
%bc = select i1 %c, i1 true, i1 %b
%or = select i1 %bc, i1 %ac, i1 false
ret i1 %or
}
define i1 @or_logic_or_logic_and_8(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_logic_or_logic_and_8(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %a, %c
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %bc, i1 %ac, i1 false
ret i1 %or
}
define <3 x i1> @or_logic_or_logic_and_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @or_logic_or_logic_and_vector(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[TMP1]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = or <3 x i1> %c, %a
%bc = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %b
%or = select <3 x i1> %ac, <3 x i1> %bc, <3 x i1> <i1 false, i1 false, i1 false>
ret <3 x i1> %or
}
define <3 x i1> @or_logic_or_logic_and_vector_poison1(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @or_logic_or_logic_and_vector_poison1(
; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> <i1 true, i1 poison, i1 true>, <3 x i1> [[BC]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = or <3 x i1> %c, %a
%bc = select <3 x i1> %c, <3 x i1> <i1 true, i1 poison, i1 true>, <3 x i1> %b
%or = select <3 x i1> %ac, <3 x i1> %bc, <3 x i1> <i1 false, i1 false, i1 false>
ret <3 x i1> %or
}
define <3 x i1> @or_logic_or_logic_and_vector_poison2(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @or_logic_or_logic_and_vector_poison2(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> [[TMP1]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = or <3 x i1> %c, %a
%bc = select <3 x i1> %c, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %b
%or = select <3 x i1> %ac, <3 x i1> %bc, <3 x i1> <i1 false, i1 false, i1 poison>
ret <3 x i1> %or
}
define i1 @or_logic_or_logic_and_not_one_use(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_logic_or_logic_and_not_one_use(
; CHECK-NEXT: [[AC:%.*]] = or i1 [[C:%.*]], [[A:%.*]]
; CHECK-NEXT: [[BC:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[C]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[B]], i1 [[AC]], i1 [[C]]
; CHECK-NEXT: call void @use(i1 [[AC]])
; CHECK-NEXT: call void @use(i1 [[BC]])
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %c, %a
%bc = select i1 %b, i1 true, i1 %c
%or = select i1 %bc, i1 %ac, i1 false
call void @use(i1 %ac)
call void @use(i1 %bc)
ret i1 %or
}
define i1 @or_or_logic_and_1(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_or_logic_and_1(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %c, %a
%bc = or i1 %b, %c
%or = select i1 %ac, i1 %bc, i1 false
ret i1 %or
}
define i1 @or_or_logic_and_2(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_or_logic_and_2(
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false
; CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %c, %a
%bc = or i1 %b, %c
%or = select i1 %bc, i1 %ac, i1 false
ret i1 %or
}
define <3 x i1> @or_or_logic_and_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @or_or_logic_and_vector(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = or <3 x i1> %c, %a
%bc = or <3 x i1> %b, %c
%or = select <3 x i1> %ac, <3 x i1> %bc, <3 x i1> <i1 false, i1 false, i1 false>
ret <3 x i1> %or
}
define <3 x i1> @or_or_logic_and_vector_poison(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) {
; CHECK-LABEL: @or_or_logic_and_vector_poison(
; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = or <3 x i1> [[TMP1]], [[C:%.*]]
; CHECK-NEXT: ret <3 x i1> [[OR]]
;
%ac = or <3 x i1> %c, %a
%bc = or <3 x i1> %b, %c
%or = select <3 x i1> %ac, <3 x i1> %bc, <3 x i1> <i1 poison, i1 false, i1 false>
ret <3 x i1> %or
}
define i1 @or_or_logic_and_not_one_use(i1 %c, i1 %a, i1 %b) {
; CHECK-LABEL: @or_or_logic_and_not_one_use(
; CHECK-NEXT: [[AC:%.*]] = or i1 [[C:%.*]], [[A:%.*]]
; CHECK-NEXT: [[BC:%.*]] = or i1 [[B:%.*]], [[C]]
; CHECK-NEXT: [[OR:%.*]] = select i1 [[B]], i1 [[AC]], i1 [[C]]
; CHECK-NEXT: call void @use(i1 [[AC]])
; CHECK-NEXT: call void @use(i1 [[BC]])
; CHECK-NEXT: ret i1 [[OR]]
;
%ac = or i1 %c, %a
%bc = or i1 %b, %c
%or = select i1 %bc, i1 %ac, i1 false
call void @use(i1 %ac)
call void @use(i1 %bc)
ret i1 %or
}