aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorJulius Alexandre <juliuswoosebert@gmail.com>2024-07-30 22:00:46 -0400
committerGitHub <noreply@github.com>2024-07-30 19:00:46 -0700
commit7231776a0218033ea81f73e69ca4bf66734d3117 (patch)
treef2ff5a2ce803e1e1812e8adb9e1d2b7d98e418ce /llvm/lib/CodeGen
parent41003ff3fe344dee5c963d462a4bc6d528811d86 (diff)
downloadllvm-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.cpp20
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))