Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2750,6 +2750,24 @@ } } + // (A | B) | (C & D) + if (match(Op0, m_Or(m_Value(A), m_Value(B))) && + match(Op1, m_And(m_Value(C), m_Value(D)))) { + const APInt *C0, *C1; + // (A | (B & C0)) | (B & C1) -> A | (B & C0|C1) + if (match(B, m_c_And(m_Specific(C), m_APInt(C0))) && + match(D, m_APInt(C1))) { + Constant *C01 = ConstantInt::get(Ty, *C0 | *C1); + return BinaryOperator::CreateOr(A, Builder.CreateAnd(C, C01)); + } + // ((B & C0) | A) | (B & C1) -> (B & C0|C1) | A + if (match(A, m_c_And(m_Specific(C), m_APInt(C0))) && + match(D, m_APInt(C1))) { + Constant *C01 = ConstantInt::get(Ty, *C0 | *C1); + return BinaryOperator::CreateOr(Builder.CreateAnd(C, C01), B); + } + } + // (A ^ B) | ((B ^ C) ^ A) -> (A ^ B) | C if (match(Op0, m_Xor(m_Value(A), m_Value(B)))) if (match(Op1, m_Xor(m_Xor(m_Specific(B), m_Value(C)), m_Specific(A)))) Index: llvm/test/Transforms/InstCombine/and-or.ll =================================================================== --- llvm/test/Transforms/InstCombine/and-or.ll +++ llvm/test/Transforms/InstCombine/and-or.ll @@ -339,12 +339,10 @@ define i64 @or_or_and(i64 %x) { ; CHECK-LABEL: @or_or_and( ; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 8 -; CHECK-NEXT: [[SHL:%.*]] = and i64 [[TMP1]], 71776119061217280 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[X]], 8 ; CHECK-NEXT: [[SHL3:%.*]] = and i64 [[TMP2]], -72057594037927936 -; CHECK-NEXT: [[OR:%.*]] = or i64 [[SHL]], [[SHL3]] -; CHECK-NEXT: [[SHL6:%.*]] = and i64 [[TMP1]], 1095216660480 -; CHECK-NEXT: [[OR7:%.*]] = or i64 [[OR]], [[SHL6]] +; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP1]], 71777214277877760 +; CHECK-NEXT: [[OR7:%.*]] = or i64 [[TMP3]], [[SHL3]] ; CHECK-NEXT: ret i64 [[OR7]] ; %1 = lshr i64 %x, 8 @@ -361,12 +359,10 @@ define i64 @or_or_and_commute0(i64 %x) { ; CHECK-LABEL: @or_or_and_commute0( ; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[X:%.*]], 8 -; CHECK-NEXT: [[SHL:%.*]] = and i64 [[TMP1]], 71776119061217280 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[X]], 8 ; CHECK-NEXT: [[SHL3:%.*]] = and i64 [[TMP2]], -72057594037927936 -; CHECK-NEXT: [[OR:%.*]] = or i64 [[SHL3]], [[SHL]] -; CHECK-NEXT: [[SHL6:%.*]] = and i64 [[TMP1]], 1095216660480 -; CHECK-NEXT: [[OR7:%.*]] = or i64 [[OR]], [[SHL6]] +; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP1]], 71777214277877760 +; CHECK-NEXT: [[OR7:%.*]] = or i64 [[SHL3]], [[TMP3]] ; CHECK-NEXT: ret i64 [[OR7]] ; %1 = lshr i64 %x, 8 @@ -382,22 +378,10 @@ define i64 @or_or_or_and_complex(i64 noundef %i) { ; CHECK-LABEL: @or_or_or_and_complex( ; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[I:%.*]], 8 -; CHECK-NEXT: [[SHL:%.*]] = and i64 [[TMP1]], 71776119061217280 ; CHECK-NEXT: [[TMP2:%.*]] = shl i64 [[I]], 8 -; CHECK-NEXT: [[SHL3:%.*]] = and i64 [[TMP2]], -72057594037927936 -; CHECK-NEXT: [[OR:%.*]] = or i64 [[SHL]], [[SHL3]] -; CHECK-NEXT: [[SHL6:%.*]] = and i64 [[TMP1]], 1095216660480 -; CHECK-NEXT: [[OR7:%.*]] = or i64 [[OR]], [[SHL6]] -; CHECK-NEXT: [[SHL10:%.*]] = and i64 [[TMP2]], 280375465082880 -; CHECK-NEXT: [[OR11:%.*]] = or i64 [[OR7]], [[SHL10]] -; CHECK-NEXT: [[SHL14:%.*]] = and i64 [[TMP1]], 16711680 -; CHECK-NEXT: [[OR15:%.*]] = or i64 [[OR11]], [[SHL14]] -; CHECK-NEXT: [[SHL18:%.*]] = and i64 [[TMP2]], 4278190080 -; CHECK-NEXT: [[OR19:%.*]] = or i64 [[OR15]], [[SHL18]] -; CHECK-NEXT: [[AND21:%.*]] = and i64 [[TMP1]], 255 -; CHECK-NEXT: [[OR23:%.*]] = or i64 [[OR19]], [[AND21]] -; CHECK-NEXT: [[SHL26:%.*]] = and i64 [[TMP2]], 65280 -; CHECK-NEXT: [[OR27:%.*]] = or i64 [[OR23]], [[SHL26]] +; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP1]], 71777214294589695 +; CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP2]], -71777214294589696 +; CHECK-NEXT: [[OR27:%.*]] = or i64 [[TMP3]], [[TMP4]] ; CHECK-NEXT: ret i64 [[OR27]] ; %1 = lshr i64 %i, 8 Index: llvm/test/Transforms/InstCombine/or.ll =================================================================== --- llvm/test/Transforms/InstCombine/or.ll +++ llvm/test/Transforms/InstCombine/or.ll @@ -383,8 +383,8 @@ ; PR4216 define i32 @test30(i32 %A) { ; CHECK-LABEL: @test30( -; CHECK-NEXT: [[D:%.*]] = and i32 [[A:%.*]], -58312 -; CHECK-NEXT: [[E:%.*]] = or i32 [[D]], 32962 +; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], -58312 +; CHECK-NEXT: [[E:%.*]] = or i32 [[TMP1]], 32962 ; CHECK-NEXT: ret i32 [[E]] ; %B = or i32 %A, 32962 ; 0b1000_0000_1100_0010 @@ -396,10 +396,8 @@ define <2 x i32> @test30vec(<2 x i32> %A) { ; CHECK-LABEL: @test30vec( -; CHECK-NEXT: [[C:%.*]] = and <2 x i32> [[A:%.*]], -; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A]], -; CHECK-NEXT: [[D:%.*]] = or <2 x i32> [[B]], -; CHECK-NEXT: [[E:%.*]] = or <2 x i32> [[D]], [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], +; CHECK-NEXT: [[E:%.*]] = or <2 x i32> [[TMP1]], ; CHECK-NEXT: ret <2 x i32> [[E]] ; %B = or <2 x i32> %A,