llvm.org GIT mirror llvm / 40263ea
[DAG] isBitwiseNot / isConstOrConstSplat - add support for build vector undefs + truncation (PR41020) Add (opt-in) support for implicit truncation to isConstOrConstSplat, which allows us to match truncated 'all ones' cases in isBitwiseNot. PR41020 compares against using ISD::isBuildVectorAllOnes() instead, but that predicate silently accepts any UNDEF elements in the build vector which might not be what we want in isBitwiseNot - so I've added an opt-in 'AllowUndefs' flag that is set to false by default but will allow us to enable it on individual cases where its safe. Differential Revision: https://reviews.llvm.org/D62783 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362323 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Pilgrim 4 months ago
3 changed file(s) with 43 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
16481648
16491649 /// Returns true if \p V is a bitwise not operation. Assumes that an all ones
16501650 /// constant is canonicalized to be operand 1.
1651 bool isBitwiseNot(SDValue V);
1651 bool isBitwiseNot(SDValue V, bool AllowUndefs = false);
16521652
16531653 /// Returns the SDNode if it is a constant splat BuildVector or constant int.
1654 ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false);
1654 ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false,
1655 bool AllowTruncation = false);
16551656
16561657 /// Returns the SDNode if it is a demanded constant splat BuildVector or
16571658 /// constant int.
16581659 ConstantSDNode *isConstOrConstSplat(SDValue N, const APInt &DemandedElts,
1659 bool AllowUndefs = false);
1660 bool AllowUndefs = false,
1661 bool AllowTruncation = false);
16601662
16611663 /// Returns the SDNode if it is a constant splat BuildVector or constant float.
16621664 ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, bool AllowUndefs = false);
86398639 return V;
86408640 }
86418641
8642 bool llvm::isBitwiseNot(SDValue V) {
8642 bool llvm::isBitwiseNot(SDValue V, bool AllowUndefs) {
86438643 if (V.getOpcode() != ISD::XOR)
86448644 return false;
8645 ConstantSDNode *C = isConstOrConstSplat(peekThroughBitcasts(V.getOperand(1)));
8646 return C && C->isAllOnesValue();
8647 }
8648
8649 ConstantSDNode *llvm::isConstOrConstSplat(SDValue N, bool AllowUndefs) {
8645 V = peekThroughBitcasts(V.getOperand(1));
8646 unsigned NumBits = V.getScalarValueSizeInBits();
8647 ConstantSDNode *C =
8648 isConstOrConstSplat(V, AllowUndefs, /*AllowTruncation*/ true);
8649 return C && (C->getAPIntValue().countTrailingOnes() >= NumBits);
8650 }
8651
8652 ConstantSDNode *llvm::isConstOrConstSplat(SDValue N, bool AllowUndefs,
8653 bool AllowTruncation) {
86508654 if (ConstantSDNode *CN = dyn_cast(N))
86518655 return CN;
86528656
86548658 BitVector UndefElements;
86558659 ConstantSDNode *CN = BV->getConstantSplatNode(&UndefElements);
86568660
8657 // BuildVectors can truncate their operands. Ignore that case here.
8658 if (CN && (UndefElements.none() || AllowUndefs) &&
8659 CN->getValueType(0) == N.getValueType().getScalarType())
8660 return CN;
8661 // BuildVectors can truncate their operands. Ignore that case here unless
8662 // AllowTruncation is set.
8663 if (CN && (UndefElements.none() || AllowUndefs)) {
8664 EVT CVT = CN->getValueType(0);
8665 EVT NSVT = N.getValueType().getScalarType();
8666 assert(CVT.bitsGE(NSVT) && "Illegal build vector element extension");
8667 if (AllowTruncation || (CVT == NSVT))
8668 return CN;
8669 }
86618670 }
86628671
86638672 return nullptr;
86648673 }
86658674
86668675 ConstantSDNode *llvm::isConstOrConstSplat(SDValue N, const APInt &DemandedElts,
8667 bool AllowUndefs) {
8676 bool AllowUndefs,
8677 bool AllowTruncation) {
86688678 if (ConstantSDNode *CN = dyn_cast(N))
86698679 return CN;
86708680
86728682 BitVector UndefElements;
86738683 ConstantSDNode *CN = BV->getConstantSplatNode(DemandedElts, &UndefElements);
86748684
8675 // BuildVectors can truncate their operands. Ignore that case here.
8676 if (CN && (UndefElements.none() || AllowUndefs) &&
8677 CN->getValueType(0) == N.getValueType().getScalarType())
8678 return CN;
8685 // BuildVectors can truncate their operands. Ignore that case here unless
8686 // AllowTruncation is set.
8687 if (CN && (UndefElements.none() || AllowUndefs)) {
8688 EVT CVT = CN->getValueType(0);
8689 EVT NSVT = N.getValueType().getScalarType();
8690 assert(CVT.bitsGE(NSVT) && "Illegal build vector element extension");
8691 if (AllowTruncation || (CVT == NSVT))
8692 return CN;
8693 }
86798694 }
86808695
86818696 return nullptr;
363363 ; CHECK-NEXT: movi v1.16b, #42
364364 ; CHECK-NEXT: add v1.16b, v0.16b, v1.16b
365365 ; CHECK-NEXT: cmhi v0.16b, v0.16b, v1.16b
366 ; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
367 ; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
366 ; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
368367 ; CHECK-NEXT: ret
369368 %a = add <16 x i8> %x,
370369 %c = icmp ugt <16 x i8> %x, %a
379378 ; CHECK-NEXT: movi v2.16b, #213
380379 ; CHECK-NEXT: add v1.16b, v0.16b, v1.16b
381380 ; CHECK-NEXT: cmhi v0.16b, v0.16b, v2.16b
382 ; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
383 ; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
381 ; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
384382 ; CHECK-NEXT: ret
385383 %a = add <16 x i8> %x,
386384 %c = icmp ugt <16 x i8> %x,
408406 ; CHECK-NEXT: movi v1.8h, #42
409407 ; CHECK-NEXT: add v1.8h, v0.8h, v1.8h
410408 ; CHECK-NEXT: cmhi v0.8h, v0.8h, v1.8h
411 ; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
412 ; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
409 ; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
413410 ; CHECK-NEXT: ret
414411 %a = add <8 x i16> %x,
415412 %c = icmp ugt <8 x i16> %x, %a
424421 ; CHECK-NEXT: mvni v2.8h, #42
425422 ; CHECK-NEXT: add v1.8h, v0.8h, v1.8h
426423 ; CHECK-NEXT: cmhi v0.8h, v0.8h, v2.8h
427 ; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
428 ; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
424 ; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
429425 ; CHECK-NEXT: ret
430426 %a = add <8 x i16> %x,
431427 %c = icmp ugt <8 x i16> %x,
544540 ; CHECK: // %bb.0:
545541 ; CHECK-NEXT: add v1.16b, v0.16b, v1.16b
546542 ; CHECK-NEXT: cmhi v0.16b, v0.16b, v1.16b
547 ; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
548 ; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
543 ; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
549544 ; CHECK-NEXT: ret
550545 %a = add <16 x i8> %x, %y
551546 %c = icmp ugt <16 x i8> %x, %a
559554 ; CHECK-NEXT: mvn v2.16b, v1.16b
560555 ; CHECK-NEXT: add v1.16b, v0.16b, v1.16b
561556 ; CHECK-NEXT: cmhi v0.16b, v0.16b, v2.16b
562 ; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
563 ; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
557 ; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
564558 ; CHECK-NEXT: ret
565559 %noty = xor <16 x i8> %y,
566560 %a = add <16 x i8> %x, %y
588582 ; CHECK: // %bb.0:
589583 ; CHECK-NEXT: add v1.8h, v0.8h, v1.8h
590584 ; CHECK-NEXT: cmhi v0.8h, v0.8h, v1.8h
591 ; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
592 ; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
585 ; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
593586 ; CHECK-NEXT: ret
594587 %a = add <8 x i16> %x, %y
595588 %c = icmp ugt <8 x i16> %x, %a
603596 ; CHECK-NEXT: mvn v2.16b, v1.16b
604597 ; CHECK-NEXT: add v1.8h, v0.8h, v1.8h
605598 ; CHECK-NEXT: cmhi v0.8h, v0.8h, v2.8h
606 ; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
607 ; CHECK-NEXT: orr v0.16b, v0.16b, v1.16b
599 ; CHECK-NEXT: orr v0.16b, v1.16b, v0.16b
608600 ; CHECK-NEXT: ret
609601 %noty = xor <8 x i16> %y,
610602 %a = add <8 x i16> %x, %y