Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2279,10 +2279,12 @@ return DAG.getNode(ISD::SUB, DL, VT, N0, AndOp0); } - // add (sext i1), X -> sub X, (zext i1) + // If the target's bool is represented as 0/1, prefer to make this 'sub 0/1' + // rather than 'add 0/-1' (the zext should get folded). + // add (sext i1 Y), X --> sub X, (zext i1 Y) if (N0.getOpcode() == ISD::SIGN_EXTEND && - N0.getOperand(0).getValueType() == MVT::i1 && - !TLI.isOperationLegal(ISD::SIGN_EXTEND, MVT::i1)) { + N0.getOperand(0).getScalarValueSizeInBits() == 1 && + TLI.getBooleanContents(VT) == TargetLowering::ZeroOrOneBooleanContent) { SDValue ZExt = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, N0.getOperand(0)); return DAG.getNode(ISD::SUB, DL, VT, N1, ZExt); } @@ -2727,6 +2729,17 @@ if (SDValue V = foldAddSubOfSignBit(N, DAG)) return V; + // If the target's bool is represented as 0/-1, prefer to make this 'add 0/-1' + // rather than 'sub 0/1' (the sext should get folded). + // sub X, (zext i1 Y) --> add X, (sext i1 Y) + if (N1.getOpcode() == ISD::ZERO_EXTEND && + N1.getOperand(0).getScalarValueSizeInBits() == 1 && + TLI.getBooleanContents(VT) == + TargetLowering::ZeroOrNegativeOneBooleanContent) { + SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND, DL, VT, N1.getOperand(0)); + return DAG.getNode(ISD::ADD, DL, VT, N0, SExt); + } + // fold Y = sra (X, size(X)-1); sub (xor (X, Y), Y) -> (abs X) if (TLI.isOperationLegalOrCustom(ISD::ABS, VT)) { if (N0.getOpcode() == ISD::XOR && N1.getOpcode() == ISD::SRA) { Index: test/CodeGen/AArch64/bool-ext-inc.ll =================================================================== --- test/CodeGen/AArch64/bool-ext-inc.ll +++ test/CodeGen/AArch64/bool-ext-inc.ll @@ -17,9 +17,7 @@ ; CHECK-LABEL: zextbool_sub_vector: ; CHECK: // %bb.0: ; CHECK-NEXT: cmeq v0.4s, v0.4s, v1.4s -; CHECK-NEXT: movi v1.4s, #1 -; CHECK-NEXT: and v0.16b, v0.16b, v1.16b -; CHECK-NEXT: sub v0.4s, v2.4s, v0.4s +; CHECK-NEXT: add v0.4s, v2.4s, v0.4s ; CHECK-NEXT: ret %c = icmp eq <4 x i32> %c1, %c2 %b = zext <4 x i1> %c to <4 x i32> Index: test/CodeGen/PowerPC/bool-math.ll =================================================================== --- test/CodeGen/PowerPC/bool-math.ll +++ test/CodeGen/PowerPC/bool-math.ll @@ -83,9 +83,8 @@ define i32 @low_bit_select_constants_bigger_false_same_size_result(i32 %x) { ; CHECK-LABEL: low_bit_select_constants_bigger_false_same_size_result: ; CHECK: # %bb.0: -; CHECK-NEXT: not 3, 3 ; CHECK-NEXT: clrldi 3, 3, 63 -; CHECK-NEXT: subfic 3, 3, 43 +; CHECK-NEXT: ori 3, 3, 42 ; CHECK-NEXT: blr %a = and i32 %x, 1 %c = icmp eq i32 %a, 0 @@ -96,9 +95,8 @@ define i64 @low_bit_select_constants_bigger_false_wider_result(i32 %x) { ; CHECK-LABEL: low_bit_select_constants_bigger_false_wider_result: ; CHECK: # %bb.0: -; CHECK-NEXT: not 3, 3 ; CHECK-NEXT: clrldi 3, 3, 63 -; CHECK-NEXT: subfic 3, 3, 27 +; CHECK-NEXT: ori 3, 3, 26 ; CHECK-NEXT: blr %a = and i32 %x, 1 %c = icmp eq i32 %a, 0 @@ -109,9 +107,8 @@ define i16 @low_bit_select_constants_bigger_false_narrower_result(i32 %x) { ; CHECK-LABEL: low_bit_select_constants_bigger_false_narrower_result: ; CHECK: # %bb.0: -; CHECK-NEXT: nor 3, 3, 3 -; CHECK-NEXT: clrlwi 3, 3, 31 -; CHECK-NEXT: subfic 3, 3, 37 +; CHECK-NEXT: clrldi 3, 3, 63 +; CHECK-NEXT: ori 3, 3, 36 ; CHECK-NEXT: blr %a = and i32 %x, 1 %c = icmp eq i32 %a, 0 Index: test/CodeGen/PowerPC/select_const.ll =================================================================== --- test/CodeGen/PowerPC/select_const.ll +++ test/CodeGen/PowerPC/select_const.ll @@ -266,10 +266,13 @@ ret i32 %sel } +; FIXME: This could be addi 3, 3, 42 + define i32 @select_C_Cplus1_signext(i1 signext %cond) { ; ALL-LABEL: select_C_Cplus1_signext: ; ALL: # %bb.0: -; ALL-NEXT: addi 3, 3, 42 +; ALL-NEXT: clrldi 3, 3, 63 +; ALL-NEXT: subfic 3, 3, 42 ; ALL-NEXT: blr %sel = select i1 %cond, i32 41, i32 42 ret i32 %sel Index: test/CodeGen/PowerPC/signbit-shift.ll =================================================================== --- test/CodeGen/PowerPC/signbit-shift.ll +++ test/CodeGen/PowerPC/signbit-shift.ll @@ -69,9 +69,8 @@ define i32 @add_sext_ifpos(i32 %x) { ; CHECK-LABEL: add_sext_ifpos: ; CHECK: # %bb.0: -; CHECK-NEXT: nor 3, 3, 3 -; CHECK-NEXT: srawi 3, 3, 31 -; CHECK-NEXT: addi 3, 3, 42 +; CHECK-NEXT: srwi 3, 3, 31 +; CHECK-NEXT: addi 3, 3, 41 ; CHECK-NEXT: blr %c = icmp sgt i32 %x, -1 %e = sext i1 %c to i32 Index: test/CodeGen/X86/bool-ext-inc.ll =================================================================== --- test/CodeGen/X86/bool-ext-inc.ll +++ test/CodeGen/X86/bool-ext-inc.ll @@ -118,8 +118,7 @@ ; CHECK-LABEL: zextbool_sub_vector: ; CHECK: # %bb.0: ; CHECK-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm0 -; CHECK-NEXT: vpsrld $31, %xmm0, %xmm0 -; CHECK-NEXT: vpsubd %xmm0, %xmm2, %xmm0 +; CHECK-NEXT: vpaddd %xmm0, %xmm2, %xmm0 ; CHECK-NEXT: retq %c = icmp eq <4 x i32> %cmp1, %cmp2 %b = zext <4 x i1> %c to <4 x i32>