if (SDValue V = foldAddSubMasked1(true, N0, N1, DAG, DL))
return V;
- // 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);
}
if (SDValue V = foldAddSubMasked1(false, N0, N1, DAG, SDLoc(N)))
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) {
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
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
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
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