return V;
}
-bool llvm::isBitwiseNot(SDValue V) {
+bool llvm::isBitwiseNot(SDValue V, bool AllowUndefs) {
if (V.getOpcode() != ISD::XOR)
return false;
- ConstantSDNode *C = isConstOrConstSplat(peekThroughBitcasts(V.getOperand(1)));
- return C && C->isAllOnesValue();
+ V = peekThroughBitcasts(V.getOperand(1));
+ unsigned NumBits = V.getScalarValueSizeInBits();
+ ConstantSDNode *C =
+ isConstOrConstSplat(V, AllowUndefs, /*AllowTruncation*/ true);
+ return C && (C->getAPIntValue().countTrailingOnes() >= NumBits);
}
-ConstantSDNode *llvm::isConstOrConstSplat(SDValue N, bool AllowUndefs) {
+ConstantSDNode *llvm::isConstOrConstSplat(SDValue N, bool AllowUndefs,
+ bool AllowTruncation) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N))
return CN;
BitVector UndefElements;
ConstantSDNode *CN = BV->getConstantSplatNode(&UndefElements);
- // BuildVectors can truncate their operands. Ignore that case here.
- if (CN && (UndefElements.none() || AllowUndefs) &&
- CN->getValueType(0) == N.getValueType().getScalarType())
- return CN;
+ // BuildVectors can truncate their operands. Ignore that case here unless
+ // AllowTruncation is set.
+ if (CN && (UndefElements.none() || AllowUndefs)) {
+ EVT CVT = CN->getValueType(0);
+ EVT NSVT = N.getValueType().getScalarType();
+ assert(CVT.bitsGE(NSVT) && "Illegal build vector element extension");
+ if (AllowTruncation || (CVT == NSVT))
+ return CN;
+ }
}
return nullptr;
}
ConstantSDNode *llvm::isConstOrConstSplat(SDValue N, const APInt &DemandedElts,
- bool AllowUndefs) {
+ bool AllowUndefs,
+ bool AllowTruncation) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N))
return CN;
BitVector UndefElements;
ConstantSDNode *CN = BV->getConstantSplatNode(DemandedElts, &UndefElements);
- // BuildVectors can truncate their operands. Ignore that case here.
- if (CN && (UndefElements.none() || AllowUndefs) &&
- CN->getValueType(0) == N.getValueType().getScalarType())
- return CN;
+ // BuildVectors can truncate their operands. Ignore that case here unless
+ // AllowTruncation is set.
+ if (CN && (UndefElements.none() || AllowUndefs)) {
+ EVT CVT = CN->getValueType(0);
+ EVT NSVT = N.getValueType().getScalarType();
+ assert(CVT.bitsGE(NSVT) && "Illegal build vector element extension");
+ if (AllowTruncation || (CVT == NSVT))
+ return CN;
+ }
}
return nullptr;
; CHECK-NEXT: movi v1.16b, #42
; CHECK-NEXT: add v1.16b, v0.16b, v1.16b
; CHECK-NEXT: cmhi v0.16b, v0.16b, v1.16b
-; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-NEXT: ret
%a = add <16 x i8> %x, <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>
%c = icmp ugt <16 x i8> %x, %a
; CHECK-NEXT: movi v2.16b, #213
; CHECK-NEXT: add v1.16b, v0.16b, v1.16b
; CHECK-NEXT: cmhi v0.16b, v0.16b, v2.16b
-; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-NEXT: ret
%a = add <16 x i8> %x, <i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42, i8 42>
%c = icmp ugt <16 x i8> %x, <i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43, i8 -43>
; CHECK-NEXT: movi v1.8h, #42
; CHECK-NEXT: add v1.8h, v0.8h, v1.8h
; CHECK-NEXT: cmhi v0.8h, v0.8h, v1.8h
-; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-NEXT: ret
%a = add <8 x i16> %x, <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42>
%c = icmp ugt <8 x i16> %x, %a
; CHECK-NEXT: mvni v2.8h, #42
; CHECK-NEXT: add v1.8h, v0.8h, v1.8h
; CHECK-NEXT: cmhi v0.8h, v0.8h, v2.8h
-; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-NEXT: ret
%a = add <8 x i16> %x, <i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42, i16 42>
%c = icmp ugt <8 x i16> %x, <i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43, i16 -43>
; CHECK: // %bb.0:
; CHECK-NEXT: add v1.16b, v0.16b, v1.16b
; CHECK-NEXT: cmhi v0.16b, v0.16b, v1.16b
-; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-NEXT: ret
%a = add <16 x i8> %x, %y
%c = icmp ugt <16 x i8> %x, %a
; CHECK-NEXT: mvn v2.16b, v1.16b
; CHECK-NEXT: add v1.16b, v0.16b, v1.16b
; CHECK-NEXT: cmhi v0.16b, v0.16b, v2.16b
-; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-NEXT: ret
%noty = xor <16 x i8> %y, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
%a = add <16 x i8> %x, %y
; CHECK: // %bb.0:
; CHECK-NEXT: add v1.8h, v0.8h, v1.8h
; CHECK-NEXT: cmhi v0.8h, v0.8h, v1.8h
-; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-NEXT: ret
%a = add <8 x i16> %x, %y
%c = icmp ugt <8 x i16> %x, %a
; CHECK-NEXT: mvn v2.16b, v1.16b
; CHECK-NEXT: add v1.8h, v0.8h, v1.8h
; CHECK-NEXT: cmhi v0.8h, v0.8h, v2.8h
-; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
+; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-NEXT: ret
%noty = xor <8 x i16> %y, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
%a = add <8 x i16> %x, %y