diff options
author | Julius Alexandre <juliuswoosebert@gmail.com> | 2024-07-30 22:00:46 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-30 19:00:46 -0700 |
commit | 7231776a0218033ea81f73e69ca4bf66734d3117 (patch) | |
tree | f2ff5a2ce803e1e1812e8adb9e1d2b7d98e418ce /llvm/lib/CodeGen | |
parent | 41003ff3fe344dee5c963d462a4bc6d528811d86 (diff) | |
download | llvm-7231776a0218033ea81f73e69ca4bf66734d3117.zip llvm-7231776a0218033ea81f73e69ca4bf66734d3117.tar.gz llvm-7231776a0218033ea81f73e69ca4bf66734d3117.tar.bz2 |
Recommit "[DAG] Reducing instructions by better legalization handling of AVGFLOORU for illegal data types" (#101223)
Previous reverted merge: https://github.com/llvm/llvm-project/pull/99913
Original message:
**Issue:** https://github.com/rust-lang/rust/issues/124790
**Previous PR:** https://github.com/llvm/llvm-project/pull/99614
https://rust.godbolt.org/z/T7eKP3Tvo
**Aarch64:** https://alive2.llvm.org/ce/z/dqr2Kg
**x86:** https://alive2.llvm.org/ce/z/ze88Hw
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 6fd23b5..7fa83a5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -9379,6 +9379,26 @@ SDValue TargetLowering::expandAVG(SDNode *N, SelectionDAG &DAG) const { } } + // avgflooru(lhs, rhs) -> or(lshr(add(lhs, rhs),1),shl(overflow, typesize-1)) + if (Opc == ISD::AVGFLOORU && VT.isScalarInteger() && !isTypeLegal(VT)) { + SDValue UAddWithOverflow = + DAG.getNode(ISD::UADDO, dl, DAG.getVTList(VT, MVT::i1), {RHS, LHS}); + + SDValue Sum = UAddWithOverflow.getValue(0); + SDValue Overflow = UAddWithOverflow.getValue(1); + + // Right shift the sum by 1 + SDValue One = DAG.getShiftAmountConstant(1, VT, dl); + SDValue LShrVal = DAG.getNode(ISD::SRL, dl, VT, Sum, One); + + SDValue ZeroExtOverflow = DAG.getNode(ISD::ANY_EXTEND, dl, VT, Overflow); + SDValue OverflowShl = + DAG.getNode(ISD::SHL, dl, VT, ZeroExtOverflow, + DAG.getConstant(VT.getScalarSizeInBits() - 1, dl, VT)); + + return DAG.getNode(ISD::OR, dl, VT, LShrVal, OverflowShl); + } + // avgceils(lhs, rhs) -> sub(or(lhs,rhs),ashr(xor(lhs,rhs),1)) // avgceilu(lhs, rhs) -> sub(or(lhs,rhs),lshr(xor(lhs,rhs),1)) // avgfloors(lhs, rhs) -> add(and(lhs,rhs),ashr(xor(lhs,rhs),1)) |