Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2716,6 +2716,15 @@ return SelectInst::Create(B, Builder.CreateSelect(A, One, D), Zero); if (B == D) return SelectInst::Create(Builder.CreateSelect(A, One, C), B, Zero); + } else if (FalseLogicAnd) { + if (C == A) + return SelectInst::Create(C, Builder.CreateSelect(B, One, D), Zero); + if (C == B) + return SelectInst::Create(C, Builder.CreateSelect(A, One, D), Zero); + if (D == A) + return SelectInst::Create(D, Builder.CreateSelect(B, One, C), Zero); + if (D == B) + return SelectInst::Create(D, Builder.CreateSelect(A, One, C), Zero); } } } @@ -2747,6 +2756,15 @@ return SelectInst::Create(B, One, Builder.CreateSelect(A, D, Zero)); if (B == D) return SelectInst::Create(Builder.CreateSelect(A, C, Zero), One, B); + } else if (TrueLogicOr) { + if (C == A) + return SelectInst::Create(C, One, Builder.CreateSelect(B, D, Zero)); + if (C == B) + return SelectInst::Create(C, One, Builder.CreateSelect(A, D, Zero)); + if (D == A) + return SelectInst::Create(D, One, Builder.CreateSelect(B, C, Zero)); + if (D == B) + return SelectInst::Create(D, One, Builder.CreateSelect(A, C, Zero)); } } } Index: llvm/test/Transforms/InstCombine/select-factorize.ll =================================================================== --- llvm/test/Transforms/InstCombine/select-factorize.ll +++ llvm/test/Transforms/InstCombine/select-factorize.ll @@ -172,9 +172,8 @@ define i1 @and_logic_and_logic_or_1(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @and_logic_and_logic_or_1( -; CHECK-NEXT: [[AC:%.*]] = and i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 true, i1 [[BC]] +; 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 @@ -185,9 +184,8 @@ define i1 @and_logic_and_logic_or_2(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @and_logic_and_logic_or_2( -; CHECK-NEXT: [[AC:%.*]] = and i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[B:%.*]], i1 [[C]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 true, i1 [[BC]] +; 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 @@ -198,9 +196,8 @@ define i1 @and_logic_and_logic_or_3(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @and_logic_and_logic_or_3( -; CHECK-NEXT: [[AC:%.*]] = and i1 [[A:%.*]], [[C:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 true, i1 [[BC]] +; 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 @@ -209,6 +206,8 @@ ret i1 %or } +; negative test: and is not last select condition + define i1 @and_logic_and_logic_or_4(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @and_logic_and_logic_or_4( ; CHECK-NEXT: [[AC:%.*]] = and i1 [[A:%.*]], [[C:%.*]] @@ -224,9 +223,8 @@ 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: [[AC:%.*]] = and <3 x i1> [[C:%.*]], [[A:%.*]] -; 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> , <3 x i1> [[BC]] +; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> , <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 @@ -250,9 +248,8 @@ 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: [[AC:%.*]] = and <3 x i1> [[C:%.*]], [[A:%.*]] -; 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> , <3 x i1> [[BC]] +; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> , <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 @@ -261,6 +258,8 @@ ret <3 x i1> %or } +; negative test: not one use for both op + 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:%.*]] @@ -516,9 +515,8 @@ define i1 @or_logic_or_logic_and_1(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @or_logic_or_logic_and_1( -; CHECK-NEXT: [[AC:%.*]] = or i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 true, i1 [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 [[BC]], i1 false +; 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 @@ -529,9 +527,8 @@ define i1 @or_logic_or_logic_and_2(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @or_logic_or_logic_and_2( -; CHECK-NEXT: [[AC:%.*]] = or i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[C]] -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 [[BC]], i1 false +; 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 @@ -540,6 +537,8 @@ ret i1 %or } +; negative test: or is not last select condition + define i1 @or_logic_or_logic_and_3(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @or_logic_or_logic_and_3( ; CHECK-NEXT: [[AC:%.*]] = or i1 [[C:%.*]], [[A:%.*]] @@ -553,6 +552,8 @@ ret i1 %or } +; negative test: or is not last select condition + define i1 @or_logic_or_logic_and_4(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @or_logic_or_logic_and_4( ; CHECK-NEXT: [[AC:%.*]] = or i1 [[C:%.*]], [[A:%.*]] @@ -568,9 +569,8 @@ 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: [[AC:%.*]] = or <3 x i1> [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> , <3 x i1> [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> [[BC]], <3 x i1> zeroinitializer +; 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> , <3 x i1> [[TMP1]] ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = or <3 x i1> %c, %a @@ -594,9 +594,8 @@ 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: [[AC:%.*]] = or <3 x i1> [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> , <3 x i1> [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> [[BC]], <3 x i1> +; 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> , <3 x i1> [[TMP1]] ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = or <3 x i1> %c, %a @@ -605,6 +604,8 @@ ret <3 x i1> %or } +; negative test: not one use for both op + 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:%.*]]