Skip to content

Commit

Permalink
[InstCombine] (~A & B) ^ A -> A | B
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D86395
  • Loading branch information
rotateright committed Oct 17, 2020
1 parent 57d3e9c commit 53e92b4
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 12 deletions.
4 changes: 4 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3335,6 +3335,10 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
match(Op1, m_Not(m_Specific(A))))
return BinaryOperator::CreateNot(Builder.CreateAnd(A, B));

// (~A & B) ^ A --> A | B -- There are 4 commuted variants.
if (match(&I, m_c_Xor(m_c_And(m_Not(m_Value(A)), m_Value(B)), m_Deferred(A))))
return BinaryOperator::CreateOr(A, B);

// (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
// TODO: Loosen one-use restriction if common operand is a constant.
Value *D;
Expand Down
16 changes: 4 additions & 12 deletions llvm/test/Transforms/InstCombine/xor.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1176,9 +1176,7 @@ define i8 @not_ashr_wrong_const(i8 %x) {

define <2 x i32> @xor_andn_commute1(<2 x i32> %a, <2 x i32> %b) {
; CHECK-LABEL: @xor_andn_commute1(
; CHECK-NEXT: [[NOTA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 -1, i32 -1>
; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[NOTA]], [[B:%.*]]
; CHECK-NEXT: [[Z:%.*]] = xor <2 x i32> [[R]], [[A]]
; CHECK-NEXT: [[Z:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: ret <2 x i32> [[Z]]
;
%nota = xor <2 x i32> %a, <i32 -1, i32 -1>
Expand All @@ -1192,9 +1190,7 @@ define <2 x i32> @xor_andn_commute1(<2 x i32> %a, <2 x i32> %b) {
define i33 @xor_andn_commute2(i33 %a, i33 %pb) {
; CHECK-LABEL: @xor_andn_commute2(
; CHECK-NEXT: [[B:%.*]] = udiv i33 42, [[PB:%.*]]
; CHECK-NEXT: [[NOTA:%.*]] = xor i33 [[A:%.*]], -1
; CHECK-NEXT: [[R:%.*]] = and i33 [[B]], [[NOTA]]
; CHECK-NEXT: [[Z:%.*]] = xor i33 [[R]], [[A]]
; CHECK-NEXT: [[Z:%.*]] = or i33 [[B]], [[A:%.*]]
; CHECK-NEXT: ret i33 [[Z]]
;
%b = udiv i33 42, %pb ; thwart complexity-based canonicalization
Expand All @@ -1209,9 +1205,7 @@ define i33 @xor_andn_commute2(i33 %a, i33 %pb) {
define i32 @xor_andn_commute3(i32 %pa, i32 %b) {
; CHECK-LABEL: @xor_andn_commute3(
; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA:%.*]]
; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1
; CHECK-NEXT: [[R:%.*]] = and i32 [[NOTA]], [[B:%.*]]
; CHECK-NEXT: [[Z:%.*]] = xor i32 [[A]], [[R]]
; CHECK-NEXT: [[Z:%.*]] = or i32 [[A]], [[B:%.*]]
; CHECK-NEXT: ret i32 [[Z]]
;
%a = udiv i32 42, %pa ; thwart complexity-based canonicalization
Expand All @@ -1227,9 +1221,7 @@ define i32 @xor_andn_commute4(i32 %pa, i32 %pb) {
; CHECK-LABEL: @xor_andn_commute4(
; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA:%.*]]
; CHECK-NEXT: [[B:%.*]] = udiv i32 42, [[PB:%.*]]
; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1
; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[NOTA]]
; CHECK-NEXT: [[Z:%.*]] = xor i32 [[A]], [[R]]
; CHECK-NEXT: [[Z:%.*]] = or i32 [[A]], [[B]]
; CHECK-NEXT: ret i32 [[Z]]
;
%a = udiv i32 42, %pa ; thwart complexity-based canonicalization
Expand Down

0 comments on commit 53e92b4

Please sign in to comment.