return SDValue();
// The shift must be of a 'not' value.
- // TODO: Use isBitwiseNot() if it works with vectors.
SDValue Not = ShiftOp.getOperand(0);
- if (!Not.hasOneUse() || Not.getOpcode() != ISD::XOR ||
- !isAllOnesConstantOrAllOnesSplatConstant(Not.getOperand(1)))
+ if (!Not.hasOneUse() || !isBitwiseNot(Not))
return SDValue();
// The shift must be moving the sign bit to the least-significant-bit.
}
bool llvm::isBitwiseNot(SDValue V) {
- return V.getOpcode() == ISD::XOR && isAllOnesConstant(V.getOperand(1));
+ if (V.getOpcode() != ISD::XOR)
+ return false;
+ ConstantSDNode *C = isConstOrConstSplat(V.getOperand(1));
+ return C && C->isAllOnesValue();
}
ConstantSDNode *llvm::isConstOrConstSplat(SDValue N) {
;
; X64-LINUX-LABEL: inc_not_vec:
; X64-LINUX: # %bb.0:
-; X64-LINUX-NEXT: pcmpeqd %xmm1, %xmm1
-; X64-LINUX-NEXT: pxor %xmm1, %xmm0
-; X64-LINUX-NEXT: psubd %xmm1, %xmm0
+; X64-LINUX-NEXT: pxor %xmm1, %xmm1
+; X64-LINUX-NEXT: psubd %xmm0, %xmm1
+; X64-LINUX-NEXT: movdqa %xmm1, %xmm0
; X64-LINUX-NEXT: retq
;
; X64-WIN32-LABEL: inc_not_vec:
; X64-WIN32: # %bb.0:
-; X64-WIN32-NEXT: pcmpeqd %xmm1, %xmm1
-; X64-WIN32-NEXT: movdqa (%rcx), %xmm0
-; X64-WIN32-NEXT: pxor %xmm1, %xmm0
-; X64-WIN32-NEXT: psubd %xmm1, %xmm0
+; X64-WIN32-NEXT: pxor %xmm0, %xmm0
+; X64-WIN32-NEXT: psubd (%rcx), %xmm0
; X64-WIN32-NEXT: retq
%nota = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1>
%r = add <4 x i32> %nota, <i32 1, i32 1, i32 1, i32 1>
; ALL-LABEL: shrink_xor_constant1_splat:
; ALL: # %bb.0:
; ALL-NEXT: psrld $31, %xmm0
-; ALL-NEXT: pandn {{.*}}(%rip), %xmm0
+; ALL-NEXT: pxor {{.*}}(%rip), %xmm0
; ALL-NEXT: retq
%sh = lshr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>
%not = xor <4 x i32> %sh, <i32 -1, i32 -1, i32 -1, i32 -1>