Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1520,8 +1520,13 @@ return BinaryOperator::CreateNot(Op1); if (Constant *C = dyn_cast(Op0)) { + Value *X; + // C - zext(bool) -> bool ? C - 1 : C + if (match(Op1, m_ZExt(m_Value(X))) && + X->getType()->getScalarSizeInBits() == 1) + return SelectInst::Create(X, SubOne(C), C); + // C - ~X == X + (1+C) - Value *X = nullptr; if (match(Op1, m_Not(m_Value(X)))) return BinaryOperator::CreateAdd(X, AddOne(C)); Index: llvm/trunk/test/Transforms/InstCombine/zext-bool-add-sub.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/zext-bool-add-sub.ll +++ llvm/trunk/test/Transforms/InstCombine/zext-bool-add-sub.ll @@ -20,8 +20,7 @@ define i32 @zextsub(i1 %x) { ; CHECK-LABEL: @zextsub( -; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 %x to i32 -; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 11, [[ZEXT]] +; CHECK-NEXT: [[SUB:%.*]] = select i1 %x, i32 10, i32 11 ; CHECK-NEXT: ret i32 [[SUB]] ; %zext = zext i1 %x to i32 @@ -31,8 +30,7 @@ define <2 x i32> @zextsub_splat(<2 x i1> %x) { ; CHECK-LABEL: @zextsub_splat( -; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i1> %x to <2 x i32> -; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> , [[ZEXT]] +; CHECK-NEXT: [[SUB:%.*]] = select <2 x i1> %x, <2 x i32> , <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[SUB]] ; %zext = zext <2 x i1> %x to <2 x i32> @@ -42,8 +40,7 @@ define <2 x i32> @zextsub_vec(<2 x i1> %x) { ; CHECK-LABEL: @zextsub_vec( -; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i1> %x to <2 x i32> -; CHECK-NEXT: [[SUB:%.*]] = sub nsw <2 x i32> , [[ZEXT]] +; CHECK-NEXT: [[SUB:%.*]] = select <2 x i1> %x, <2 x i32> , <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[SUB]] ; %zext = zext <2 x i1> %x to <2 x i32>