diff options
author | Craig Topper <craig.topper@sifive.com> | 2024-02-17 11:37:13 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-17 11:37:13 -0800 |
commit | d5167c84f9eddf6a37c667d4673bf694dfd8be37 (patch) | |
tree | 6abadeae3d6390fcacc5bc66741ea38d7907bf6f | |
parent | 80747616b9ae5f1156954b87ba7502398573825a (diff) |
[DAGCombiner] Allow tryToFoldExtOfLoad to use a sextload for zext nneg. (#81714)
If the load is used by any signed setccs, we can use a sextload
instead of zextload. Then we don't have to give up on extending
the load.
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 39 | ||||
-rw-r--r-- | llvm/test/CodeGen/RISCV/load-setcc-combine.ll | 28 |
2 files changed, 57 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 18037f11ee40..2a09e44e1929 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -13171,20 +13171,39 @@ static SDValue tryToFoldExtOfExtload(SelectionDAG &DAG, DAGCombiner &Combiner, // fold ([s|z]ext (load x)) -> ([s|z]ext (truncate ([s|z]extload x))) // Only generate vector extloads when 1) they're legal, and 2) they are -// deemed desirable by the target. +// deemed desirable by the target. NonNegZExt can be set to true if a zero +// extend has the nonneg flag to allow use of sextload if profitable. static SDValue tryToFoldExtOfLoad(SelectionDAG &DAG, DAGCombiner &Combiner, const TargetLowering &TLI, EVT VT, bool LegalOperations, SDNode *N, SDValue N0, ISD::LoadExtType ExtLoadType, - ISD::NodeType ExtOpc) { + ISD::NodeType ExtOpc, + bool NonNegZExt = false) { + if (!ISD::isNON_EXTLoad(N0.getNode()) || !ISD::isUNINDEXEDLoad(N0.getNode())) + return {}; + + // If this is zext nneg, see if it would make sense to treat it as a sext. + if (NonNegZExt) { + assert(ExtLoadType == ISD::ZEXTLOAD && ExtOpc == ISD::ZERO_EXTEND && + "Unexpected load type or opcode"); + for (SDNode *User : N0->uses()) { + if (User->getOpcode() == ISD::SETCC) { + ISD::CondCode CC = cast<CondCodeSDNode>(User->getOperand(2))->get(); + if (ISD::isSignedIntSetCC(CC)) { + ExtLoadType = ISD::SEXTLOAD; + ExtOpc = ISD::SIGN_EXTEND; + break; + } + } + } + } + // TODO: isFixedLengthVector() should be removed and any negative effects on // code generation being the result of that target's implementation of // isVectorLoadExtDesirable(). - if (!ISD::isNON_EXTLoad(N0.getNode()) || - !ISD::isUNINDEXEDLoad(N0.getNode()) || - ((LegalOperations || VT.isFixedLengthVector() || - !cast<LoadSDNode>(N0)->isSimple()) && - !TLI.isLoadExtLegal(ExtLoadType, VT, N0.getValueType()))) + if ((LegalOperations || VT.isFixedLengthVector() || + !cast<LoadSDNode>(N0)->isSimple()) && + !TLI.isLoadExtLegal(ExtLoadType, VT, N0.getValueType())) return {}; bool DoXform = true; @@ -13780,9 +13799,9 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { } // Try to simplify (zext (load x)). - if (SDValue foldedExt = - tryToFoldExtOfLoad(DAG, *this, TLI, VT, LegalOperations, N, N0, - ISD::ZEXTLOAD, ISD::ZERO_EXTEND)) + if (SDValue foldedExt = tryToFoldExtOfLoad( + DAG, *this, TLI, VT, LegalOperations, N, N0, ISD::ZEXTLOAD, + ISD::ZERO_EXTEND, N->getFlags().hasNonNeg())) return foldedExt; if (SDValue foldedExt = diff --git a/llvm/test/CodeGen/RISCV/load-setcc-combine.ll b/llvm/test/CodeGen/RISCV/load-setcc-combine.ll new file mode 100644 index 000000000000..403999b93126 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/load-setcc-combine.ll @@ -0,0 +1,28 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc < %s -mtriple=riscv64 | FileCheck %s + +define i8 @zext_nonneg_load_i16(ptr %x, ptr %y) { +; CHECK-LABEL: zext_nonneg_load_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: lh a0, 0(a0) +; CHECK-NEXT: bltz a0, .LBB0_2 +; CHECK-NEXT: # %bb.1: # %cont +; CHECK-NEXT: add a0, a1, a0 +; CHECK-NEXT: lbu a0, 0(a0) +; CHECK-NEXT: ret +; CHECK-NEXT: .LBB0_2: # %exit +; CHECK-NEXT: li a0, 0 +; CHECK-NEXT: ret + %a = load i16, ptr %x + %b = icmp slt i16 %a, 0 + br i1 %b, label %exit, label %cont + +cont: + %c = zext nneg i16 %a to i64 + %d = getelementptr i8, ptr %y, i64 %c + %e = load i8, ptr %d + ret i8 %e + +exit: + ret i8 0 +} |