[InstCombine] add tests for bitwise logic; NFC
This commit is contained in:
parent
6ea5bf436a
commit
2843a1d87d
|
|
@ -1,6 +1,8 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
||||
|
||||
declare void @use(i4)
|
||||
|
||||
; PR1510
|
||||
|
||||
; (a | b) & ~(a & b) --> a ^ b
|
||||
|
|
@ -640,3 +642,229 @@ define i32 @xor_to_xnor4(float %fa, float %fb) {
|
|||
%xor = xor i32 %or1, %or2
|
||||
ret i32 %xor
|
||||
}
|
||||
|
||||
define i4 @simplify_or_common_op_commute0(i4 %x, i4 %y, i4 %z) {
|
||||
; CHECK-LABEL: @simplify_or_common_op_commute0(
|
||||
; CHECK-NEXT: [[XY:%.*]] = and i4 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = and i4 [[XY]], [[Z:%.*]]
|
||||
; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = or i4 [[NOT_XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%xy = and i4 %x, %y
|
||||
%xyz = and i4 %xy, %z
|
||||
%not_xyz = xor i4 %xyz, -1
|
||||
%r = or i4 %not_xyz, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define i4 @simplify_or_common_op_commute1(i4 %x, i4 %y, i4 %z) {
|
||||
; CHECK-LABEL: @simplify_or_common_op_commute1(
|
||||
; CHECK-NEXT: [[XY:%.*]] = and i4 [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = and i4 [[XY]], [[Z:%.*]]
|
||||
; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = or i4 [[NOT_XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%xy = and i4 %y, %x
|
||||
%xyz = and i4 %xy, %z
|
||||
%not_xyz = xor i4 %xyz, -1
|
||||
%r = or i4 %not_xyz, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define i4 @simplify_or_common_op_commute2(i4 %x, i4 %y, i4 %p, i4 %q) {
|
||||
; CHECK-LABEL: @simplify_or_common_op_commute2(
|
||||
; CHECK-NEXT: [[Z:%.*]] = mul i4 [[P:%.*]], [[P]]
|
||||
; CHECK-NEXT: [[XY:%.*]] = and i4 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = and i4 [[Z]], [[XY]]
|
||||
; CHECK-NEXT: [[XYZQ:%.*]] = and i4 [[XYZ]], [[Q:%.*]]
|
||||
; CHECK-NEXT: [[NOT_XYZQ:%.*]] = xor i4 [[XYZQ]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = or i4 [[NOT_XYZQ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%z = mul i4 %p, %p ; thwart complexity-based canonicalization
|
||||
%xy = and i4 %x, %y
|
||||
%xyz = and i4 %z, %xy
|
||||
%xyzq = and i4 %xyz, %q
|
||||
%not_xyzq = xor i4 %xyzq, -1
|
||||
%r = or i4 %not_xyzq, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define <2 x i4> @simplify_or_common_op_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %p) {
|
||||
; CHECK-LABEL: @simplify_or_common_op_commute3(
|
||||
; CHECK-NEXT: [[Z:%.*]] = mul <2 x i4> [[P:%.*]], [[P]]
|
||||
; CHECK-NEXT: [[XY:%.*]] = and <2 x i4> [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = and <2 x i4> [[Z]], [[XY]]
|
||||
; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor <2 x i4> [[XYZ]], <i4 -1, i4 -1>
|
||||
; CHECK-NEXT: [[R:%.*]] = or <2 x i4> [[NOT_XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret <2 x i4> [[R]]
|
||||
;
|
||||
%z = mul <2 x i4> %p, %p ; thwart complexity-based canonicalization
|
||||
%xy = and <2 x i4> %y, %x
|
||||
%xyz = and <2 x i4> %z, %xy
|
||||
%not_xyz = xor <2 x i4> %xyz, <i4 -1, i4 -1>
|
||||
%r = or <2 x i4> %x, %not_xyz
|
||||
ret <2 x i4> %r
|
||||
}
|
||||
|
||||
define i4 @simplify_and_common_op_commute0(i4 %x, i4 %y, i4 %z) {
|
||||
; CHECK-LABEL: @simplify_and_common_op_commute0(
|
||||
; CHECK-NEXT: [[XY:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: call void @use(i4 [[X]])
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = or i4 [[XY]], [[Z:%.*]]
|
||||
; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%xy = or i4 %x, %y
|
||||
call void @use(i4 %x)
|
||||
%xyz = or i4 %xy, %z
|
||||
%not_xyz = xor i4 %xyz, -1
|
||||
%r = and i4 %not_xyz, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define i4 @simplify_and_common_op_commute1(i4 %x, i4 %y, i4 %z) {
|
||||
; CHECK-LABEL: @simplify_and_common_op_commute1(
|
||||
; CHECK-NEXT: [[XY:%.*]] = or i4 [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = or i4 [[XY]], [[Z:%.*]]
|
||||
; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%xy = or i4 %y, %x
|
||||
%xyz = or i4 %xy, %z
|
||||
%not_xyz = xor i4 %xyz, -1
|
||||
%r = and i4 %not_xyz, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define i4 @simplify_and_common_op_commute2(i4 %x, i4 %y, i4 %p, i4 %q) {
|
||||
; CHECK-LABEL: @simplify_and_common_op_commute2(
|
||||
; CHECK-NEXT: [[Z:%.*]] = mul i4 [[P:%.*]], [[P]]
|
||||
; CHECK-NEXT: [[XY:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = or i4 [[Z]], [[XY]]
|
||||
; CHECK-NEXT: [[XYZQ:%.*]] = or i4 [[XYZ]], [[Q:%.*]]
|
||||
; CHECK-NEXT: [[NOT_XYZQ:%.*]] = xor i4 [[XYZQ]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = and i4 [[NOT_XYZQ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%z = mul i4 %p, %p ; thwart complexity-based canonicalization
|
||||
%xy = or i4 %x, %y
|
||||
%xyz = or i4 %z, %xy
|
||||
%xyzq = or i4 %xyz, %q
|
||||
%not_xyzq = xor i4 %xyzq, -1
|
||||
%r = and i4 %not_xyzq, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define <2 x i4> @simplify_and_common_op_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %p) {
|
||||
; CHECK-LABEL: @simplify_and_common_op_commute3(
|
||||
; CHECK-NEXT: [[Z:%.*]] = mul <2 x i4> [[P:%.*]], [[P]]
|
||||
; CHECK-NEXT: [[XY:%.*]] = or <2 x i4> [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = or <2 x i4> [[Z]], [[XY]]
|
||||
; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor <2 x i4> [[XYZ]], <i4 -1, i4 -1>
|
||||
; CHECK-NEXT: [[R:%.*]] = and <2 x i4> [[NOT_XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret <2 x i4> [[R]]
|
||||
;
|
||||
%z = mul <2 x i4> %p, %p ; thwart complexity-based canonicalization
|
||||
%xy = or <2 x i4> %y, %x
|
||||
%xyz = or <2 x i4> %z, %xy
|
||||
%not_xyz = xor <2 x i4> %xyz, <i4 -1, i4 -1>
|
||||
%r = and <2 x i4> %x, %not_xyz
|
||||
ret <2 x i4> %r
|
||||
}
|
||||
|
||||
define i4 @simplify_and_common_op_use1(i4 %x, i4 %y, i4 %z) {
|
||||
; CHECK-LABEL: @simplify_and_common_op_use1(
|
||||
; CHECK-NEXT: [[XY:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: call void @use(i4 [[Y]])
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = or i4 [[XY]], [[Z:%.*]]
|
||||
; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%xy = or i4 %x, %y
|
||||
call void @use(i4 %y)
|
||||
%xyz = or i4 %xy, %z
|
||||
%not_xyz = xor i4 %xyz, -1
|
||||
%r = and i4 %not_xyz, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define i4 @simplify_and_common_op_use2(i4 %x, i4 %y, i4 %z) {
|
||||
; CHECK-LABEL: @simplify_and_common_op_use2(
|
||||
; CHECK-NEXT: [[XY:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = or i4 [[XY]], [[Z:%.*]]
|
||||
; CHECK-NEXT: call void @use(i4 [[Z]])
|
||||
; CHECK-NEXT: [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%xy = or i4 %x, %y
|
||||
%xyz = or i4 %xy, %z
|
||||
call void @use(i4 %z)
|
||||
%not_xyz = xor i4 %xyz, -1
|
||||
%r = and i4 %not_xyz, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define i4 @reduce_xor_common_op_commute0(i4 %x, i4 %y, i4 %z) {
|
||||
; CHECK-LABEL: @reduce_xor_common_op_commute0(
|
||||
; CHECK-NEXT: [[XY:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = xor i4 [[XY]], [[Z:%.*]]
|
||||
; CHECK-NEXT: [[R:%.*]] = or i4 [[XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%xy = xor i4 %x, %y
|
||||
%xyz = xor i4 %xy, %z
|
||||
%r = or i4 %xyz, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define i4 @reduce_xor_common_op_commute1(i4 %x, i4 %y, i4 %z) {
|
||||
; CHECK-LABEL: @reduce_xor_common_op_commute1(
|
||||
; CHECK-NEXT: [[XY:%.*]] = xor i4 [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = xor i4 [[XY]], [[Z:%.*]]
|
||||
; CHECK-NEXT: [[R:%.*]] = or i4 [[XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%xy = xor i4 %y, %x
|
||||
%xyz = xor i4 %xy, %z
|
||||
%r = or i4 %xyz, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define i4 @annihilate_xor_common_op_commute2(i4 %x, i4 %y, i4 %p, i4 %q) {
|
||||
; CHECK-LABEL: @annihilate_xor_common_op_commute2(
|
||||
; CHECK-NEXT: [[Z:%.*]] = mul i4 [[P:%.*]], [[P]]
|
||||
; CHECK-NEXT: [[XY:%.*]] = xor i4 [[X:%.*]], [[Y:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = xor i4 [[Z]], [[XY]]
|
||||
; CHECK-NEXT: [[XYZQ:%.*]] = xor i4 [[XYZ]], [[Q:%.*]]
|
||||
; CHECK-NEXT: [[R:%.*]] = xor i4 [[XYZQ]], [[X]]
|
||||
; CHECK-NEXT: ret i4 [[R]]
|
||||
;
|
||||
%z = mul i4 %p, %p ; thwart complexity-based canonicalization
|
||||
%xy = xor i4 %x, %y
|
||||
%xyz = xor i4 %z, %xy
|
||||
%xyzq = xor i4 %xyz, %q
|
||||
%r = xor i4 %xyzq, %x
|
||||
ret i4 %r
|
||||
}
|
||||
|
||||
define <2 x i4> @reduce_xor_common_op_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %p) {
|
||||
; CHECK-LABEL: @reduce_xor_common_op_commute3(
|
||||
; CHECK-NEXT: [[Z:%.*]] = mul <2 x i4> [[P:%.*]], [[P]]
|
||||
; CHECK-NEXT: [[XY:%.*]] = xor <2 x i4> [[Y:%.*]], [[X:%.*]]
|
||||
; CHECK-NEXT: [[XYZ:%.*]] = xor <2 x i4> [[Z]], [[XY]]
|
||||
; CHECK-NEXT: [[R:%.*]] = or <2 x i4> [[XYZ]], [[X]]
|
||||
; CHECK-NEXT: ret <2 x i4> [[R]]
|
||||
;
|
||||
%z = mul <2 x i4> %p, %p ; thwart complexity-based canonicalization
|
||||
%xy = xor <2 x i4> %y, %x
|
||||
%xyz = xor <2 x i4> %z, %xy
|
||||
%r = or <2 x i4> %x, %xyz
|
||||
ret <2 x i4> %r
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue