diff options
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 6 | ||||
-rw-r--r-- | llvm/test/CodeGen/RISCV/pr40333.ll | 27 |
2 files changed, 32 insertions, 1 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 8a32d957ec5..95943f3dbaf 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -575,7 +575,11 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N, !(Subtarget.hasStdExtM() && isVariableSDivUDivURem(Src))) break; SDLoc DL(N); - return DCI.CombineTo(N, DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Src)); + // Don't add the new node to the DAGCombiner worklist, in order to avoid + // an infinite cycle due to SimplifyDemandedBits converting the + // SIGN_EXTEND back to ANY_EXTEND. + return DCI.CombineTo(N, DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Src), + false); } case RISCVISD::SplitF64: { // If the input to SplitF64 is just BuildPairF64 then the operation is diff --git a/llvm/test/CodeGen/RISCV/pr40333.ll b/llvm/test/CodeGen/RISCV/pr40333.ll new file mode 100644 index 00000000000..3f7ae8da3a2 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/pr40333.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV64I %s + +; This test case is significantly simplified from the submitted .ll but +; demonstrates the same issue. At the time of this problem report, an infinite +; loop would be created in DAGCombine, converting ANY_EXTEND to SIGN_EXTEND +; and back again. + +; TODO: This test case is also an example of where it would be cheaper to +; select SRLW, but the current lowering strategy fails to do so. + +define signext i8 @foo(i32 %a, i32 %b) nounwind { +; RV64I-LABEL: foo: +; RV64I: # %bb.0: +; RV64I-NEXT: slli a1, a1, 32 +; RV64I-NEXT: srli a1, a1, 32 +; RV64I-NEXT: slli a0, a0, 32 +; RV64I-NEXT: srli a0, a0, 32 +; RV64I-NEXT: srl a0, a0, a1 +; RV64I-NEXT: slli a0, a0, 56 +; RV64I-NEXT: srai a0, a0, 56 +; RV64I-NEXT: ret + %1 = lshr i32 %a, %b + %2 = trunc i32 %1 to i8 + ret i8 %2 +} |