Files
clang-p2996/llvm/test/Transforms/PhaseOrdering/reassociate-gvn-bdce.ll
Stanislav Mekhanoshin 7e1dc12f44 Move some tests from instcombine to phase ordering. NFC.
Tests from D113216 are now handled by Reassociate, GVN and BDCE
passes after D114462. Moving into phase ordering instead of
instcombine.
2021-11-24 12:57:02 -08:00

293 lines
9.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -reassociate -gvn -bdce -S | FileCheck %s
; (~(a | b) & c) | ~(a | (b | c)) -> ~(a | b)
; (~(a | b) & c) | ~(b | (a | c)) -> ~(a | b)
define i32 @not_or_and_or_not_or_or(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_or_and_or_not_or_or(
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%or1 = or i32 %b, %c
%or2 = or i32 %or1, %a
%not1 = xor i32 %or2, -1
%or3 = or i32 %b, %a
%not2 = xor i32 %or3, -1
%and2 = and i32 %not2, %c
%or4 = or i32 %and2, %not1
ret i32 %or4
}
define i32 @not_or_and_or_not_or_or_commute1(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_or_and_or_not_or_or_commute1(
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%or1 = or i32 %a, %c
%or2 = or i32 %or1, %b
%not1 = xor i32 %or2, -1
%or3 = or i32 %b, %a
%not2 = xor i32 %or3, -1
%and2 = and i32 %not2, %c
%or4 = or i32 %and2, %not1
ret i32 %or4
}
define i32 @not_or_and_or_not_or_or_commute2(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_or_and_or_not_or_or_commute2(
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%or1 = or i32 %c, %b
%or2 = or i32 %or1, %a
%not1 = xor i32 %or2, -1
%or3 = or i32 %b, %a
%not2 = xor i32 %or3, -1
%and2 = and i32 %not2, %c
%or4 = or i32 %and2, %not1
ret i32 %or4
}
define i32 @not_or_and_or_not_or_or_commute3(i32 %a0, i32 %b, i32 %c) {
; CHECK-LABEL: @not_or_and_or_not_or_or_commute3(
; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
%or1 = or i32 %b, %c
%or2 = or i32 %a, %or1
%not1 = xor i32 %or2, -1
%or3 = or i32 %a, %b
%not2 = xor i32 %or3, -1
%and2 = and i32 %not2, %c
%or4 = or i32 %and2, %not1
ret i32 %or4
}
define i32 @not_or_and_or_not_or_or_commute4(i32 %a, i32 %b0, i32 %c) {
; CHECK-LABEL: @not_or_and_or_not_or_or_commute4(
; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
%or1 = or i32 %a, %c
%or2 = or i32 %b, %or1
%not1 = xor i32 %or2, -1
%or3 = or i32 %b, %a
%not2 = xor i32 %or3, -1
%and2 = and i32 %not2, %c
%or4 = or i32 %and2, %not1
ret i32 %or4
}
define i32 @not_or_and_or_not_or_or_commute5(i32 %a, i32 %b, i32 %c0) {
; CHECK-LABEL: @not_or_and_or_not_or_or_commute5(
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
%or1 = or i32 %c, %a
%or2 = or i32 %or1, %b
%not1 = xor i32 %or2, -1
%or3 = or i32 %b, %a
%not2 = xor i32 %or3, -1
%and2 = and i32 %c, %not2
%or4 = or i32 %and2, %not1
ret i32 %or4
}
define i32 @not_or_and_or_not_or_or_use1(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_or_and_or_not_or_or_use1(
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C:%.*]]
; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR2]], -1
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR1]], -1
; CHECK-NEXT: call void @use(i32 [[NOT1]])
; CHECK-NEXT: ret i32 [[NOT2]]
;
%or1 = or i32 %b, %c
%or2 = or i32 %or1, %a
%not1 = xor i32 %or2, -1
%or3 = or i32 %b, %a
%not2 = xor i32 %or3, -1
%and2 = and i32 %not2, %c
%or4 = or i32 %and2, %not1
call void @use(i32 %not1)
ret i32 %or4
}
define i32 @not_or_and_or_not_or_or_use2(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_or_and_or_not_or_or_use2(
; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C:%.*]]
; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR2]], -1
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR1]], -1
; CHECK-NEXT: call void @use(i32 [[NOT1]])
; CHECK-NEXT: ret i32 [[NOT2]]
;
%or1 = or i32 %a, %c
%or2 = or i32 %or1, %b
%not1 = xor i32 %or2, -1
%or3 = or i32 %b, %a
%not2 = xor i32 %or3, -1
%and2 = and i32 %not2, %c
%or4 = or i32 %and2, %not1
call void @use(i32 %not1)
ret i32 %or4
}
; (~(a & b) | c) & ~(a & (b & c)) -> ~(a & b)
; (~(a & b) | c) & ~(b & (a & c)) -> ~(a & b)
define i32 @not_and_or_and_not_and_and(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_and_or_and_not_and_and(
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%and1 = and i32 %b, %c
%and2 = and i32 %and1, %a
%not1 = xor i32 %and2, -1
%and3 = and i32 %b, %a
%not2 = xor i32 %and3, -1
%or2 = or i32 %not2, %c
%and4 = and i32 %or2, %not1
ret i32 %and4
}
define i32 @not_and_or_and_not_and_and_commute1(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_and_or_and_not_and_and_commute1(
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%and1 = and i32 %a, %c
%and2 = and i32 %and1, %b
%not1 = xor i32 %and2, -1
%and3 = and i32 %b, %a
%not2 = xor i32 %and3, -1
%or2 = or i32 %not2, %c
%and4 = and i32 %or2, %not1
ret i32 %and4
}
define i32 @not_and_or_and_not_and_and_commute2(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_and_or_and_not_and_and_commute2(
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%and1 = and i32 %c, %b
%and2 = and i32 %and1, %a
%not1 = xor i32 %and2, -1
%and3 = and i32 %b, %a
%not2 = xor i32 %and3, -1
%or2 = or i32 %not2, %c
%and4 = and i32 %or2, %not1
ret i32 %and4
}
define i32 @not_and_or_and_not_and_and_commute3(i32 %a0, i32 %b, i32 %c) {
; CHECK-LABEL: @not_and_or_and_not_and_and_commute3(
; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
%and1 = and i32 %b, %c
%and2 = and i32 %a, %and1
%not1 = xor i32 %and2, -1
%and3 = and i32 %a, %b
%not2 = xor i32 %and3, -1
%or2 = or i32 %not2, %c
%and4 = and i32 %or2, %not1
ret i32 %and4
}
define i32 @not_and_or_and_not_and_and_commute4(i32 %a, i32 %b0, i32 %c) {
; CHECK-LABEL: @not_and_or_and_not_and_and_commute4(
; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
%and1 = and i32 %a, %c
%and2 = and i32 %b, %and1
%not1 = xor i32 %and2, -1
%and3 = and i32 %b, %a
%not2 = xor i32 %and3, -1
%or2 = or i32 %not2, %c
%and4 = and i32 %or2, %not1
ret i32 %and4
}
define i32 @not_and_or_and_not_and_and_commute5(i32 %a, i32 %b, i32 %c0) {
; CHECK-LABEL: @not_and_or_and_not_and_and_commute5(
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND1]], -1
; CHECK-NEXT: ret i32 [[NOT2]]
;
%c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
%and1 = and i32 %c, %a
%and2 = and i32 %and1, %b
%not1 = xor i32 %and2, -1
%and3 = and i32 %b, %a
%not2 = xor i32 %and3, -1
%or2 = or i32 %c, %not2
%and4 = and i32 %or2, %not1
ret i32 %and4
}
define i32 @not_and_or_and_not_and_and_use1(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_and_or_and_not_and_and_use1(
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND2]], -1
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND1]], -1
; CHECK-NEXT: call void @use(i32 [[NOT1]])
; CHECK-NEXT: ret i32 [[NOT2]]
;
%and1 = and i32 %b, %c
%and2 = and i32 %and1, %a
%not1 = xor i32 %and2, -1
%and3 = and i32 %b, %a
%not2 = xor i32 %and3, -1
%or2 = or i32 %not2, %c
%and4 = and i32 %or2, %not1
call void @use(i32 %not1)
ret i32 %and4
}
define i32 @not_and_or_and_not_and_and_use2(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: @not_and_or_and_not_and_and_use2(
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND2]], -1
; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND1]], -1
; CHECK-NEXT: call void @use(i32 [[NOT1]])
; CHECK-NEXT: ret i32 [[NOT2]]
;
%and1 = and i32 %a, %c
%and2 = and i32 %and1, %b
%not1 = xor i32 %and2, -1
%and3 = and i32 %b, %a
%not2 = xor i32 %and3, -1
%or2 = or i32 %not2, %c
%and4 = and i32 %or2, %not1
call void @use(i32 %not1)
ret i32 %and4
}
declare void @use(i32)