SDValue visitTokenFactor(SDNode *N);
SDValue visitMERGE_VALUES(SDNode *N);
SDValue visitADD(SDNode *N);
+ SDValue visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference);
SDValue visitSUB(SDNode *N);
SDValue visitADDC(SDNode *N);
SDValue visitSUBC(SDNode *N);
VT.isInteger() && DAG.haveNoCommonBitsSet(N0, N1))
return DAG.getNode(ISD::OR, DL, VT, N0, N1);
+ if (SDValue Combined = visitADDLike(N0, N1, N))
+ return Combined;
+
+ if (SDValue Combined = visitADDLike(N1, N0, N))
+ return Combined;
+
+ return SDValue();
+}
+
+SDValue DAGCombiner::visitADDLike(SDValue N0, SDValue N1, SDNode *LocReference) {
+ EVT VT = N0.getValueType();
+ SDLoc DL(LocReference);
+
// fold (add x, shl(0 - y, n)) -> sub(x, shl(y, n))
if (N1.getOpcode() == ISD::SHL && N1.getOperand(0).getOpcode() == ISD::SUB &&
isNullConstantOrNullSplatConstant(N1.getOperand(0).getOperand(0)))
DAG.getNode(ISD::SHL, DL, VT,
N1.getOperand(0).getOperand(1),
N1.getOperand(1)));
- if (N0.getOpcode() == ISD::SHL && N0.getOperand(0).getOpcode() == ISD::SUB &&
- isNullConstantOrNullSplatConstant(N0.getOperand(0).getOperand(0)))
- return DAG.getNode(ISD::SUB, DL, VT, N1,
- DAG.getNode(ISD::SHL, DL, VT,
- N0.getOperand(0).getOperand(1),
- N0.getOperand(1)));
if (N1.getOpcode() == ISD::AND) {
SDValue AndOp0 = N1.getOperand(0);
; CHECK: # BB#0: # %entry
; CHECK-NEXT: addq %rdx, %rsi
; CHECK-NEXT: sbbq %rax, %rax
-; CHECK-NEXT: andl $1, %eax
-; CHECK-NEXT: addl %ecx, %eax
-; CHECK-NEXT: movl %eax, (%rdi)
+; CHECK-NEXT: subl %eax, %ecx
+; CHECK-NEXT: movl %ecx, (%rdi)
; CHECK-NEXT: retq
entry:
%0 = zext i64 %a to i128
; CHECK: # BB#0: # %entry
; CHECK-NEXT: addq %rdx, %rsi
; CHECK-NEXT: sbbq %rax, %rax
-; CHECK-NEXT: andl $1, %eax
-; CHECK-NEXT: addl %ecx, %eax
-; CHECK-NEXT: movw %ax, (%rdi)
+; CHECK-NEXT: subl %eax, %ecx
+; CHECK-NEXT: movw %cx, (%rdi)
; CHECK-NEXT: retq
entry:
%0 = zext i64 %a to i128
; CHECK: # BB#0: # %entry
; CHECK-NEXT: addq %rdx, %rsi
; CHECK-NEXT: sbbq %rax, %rax
-; CHECK-NEXT: andl $1, %eax
-; CHECK-NEXT: addl %ecx, %eax
-; CHECK-NEXT: movb %al, (%rdi)
+; CHECK-NEXT: subl %eax, %ecx
+; CHECK-NEXT: movb %cl, (%rdi)
; CHECK-NEXT: retq
entry:
%0 = zext i64 %a to i128
; CHECK-NEXT: movq %rax, (%rdi)
; CHECK-NEXT: addq 8(%rdi), %rdx
; CHECK-NEXT: sbbq %rax, %rax
-; CHECK-NEXT: andl $1, %eax
; CHECK-NEXT: movq %rdx, 8(%rdi)
-; CHECK-NEXT: addl %eax, 16(%rdi)
+; CHECK-NEXT: subl %eax, 16(%rdi)
; CHECK-NEXT: retq
entry:
%0 = zext i64 %arg.a to i128