diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -506,6 +506,10 @@ MachineFunction &MF) const; bool useRVVForFixedLengthVectorVT(MVT VT) const; + + bool shouldNormalizeToSelectSequence(LLVMContext &, EVT) const override { + return false; + }; }; namespace RISCV { diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -688,9 +688,6 @@ // Jumps are expensive, compared to logic setJumpIsExpensive(); - // We can use any register for comparisons - setHasMultipleConditionRegisters(); - if (Subtarget.hasStdExtZbp()) { setTargetDAGCombine(ISD::OR); } diff --git a/llvm/test/CodeGen/RISCV/sink-icmp.ll b/llvm/test/CodeGen/RISCV/sink-icmp.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/sink-icmp.ll @@ -0,0 +1,131 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32I %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32IBT %s +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV64I %s +; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV64IBT %s + +define dso_local signext i16 @func(i16* %a) local_unnamed_addr #0 { +; RV32I-LABEL: func: +; RV32I: # %bb.0: # %entry +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: .cfi_def_cfa_offset 16 +; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: .cfi_offset ra, -4 +; RV32I-NEXT: lh a1, 0(a0) +; RV32I-NEXT: bltz a1, .LBB0_2 +; RV32I-NEXT: .LBB0_1: # %while.body +; RV32I-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32I-NEXT: call f +; RV32I-NEXT: bnez a0, .LBB0_1 +; RV32I-NEXT: j .LBB0_3 +; RV32I-NEXT: .LBB0_2: # %while.body5 +; RV32I-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32I-NEXT: call g +; RV32I-NEXT: bnez a0, .LBB0_2 +; RV32I-NEXT: .LBB0_3: # %return +; RV32I-NEXT: mv a0, zero +; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV32IBT-LABEL: func: +; RV32IBT: # %bb.0: # %entry +; RV32IBT-NEXT: addi sp, sp, -16 +; RV32IBT-NEXT: .cfi_def_cfa_offset 16 +; RV32IBT-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IBT-NEXT: .cfi_offset ra, -4 +; RV32IBT-NEXT: lh a1, 0(a0) +; RV32IBT-NEXT: bltz a1, .LBB0_2 +; RV32IBT-NEXT: .LBB0_1: # %while.body +; RV32IBT-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IBT-NEXT: call f +; RV32IBT-NEXT: bnez a0, .LBB0_1 +; RV32IBT-NEXT: j .LBB0_3 +; RV32IBT-NEXT: .LBB0_2: # %while.body5 +; RV32IBT-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IBT-NEXT: call g +; RV32IBT-NEXT: bnez a0, .LBB0_2 +; RV32IBT-NEXT: .LBB0_3: # %return +; RV32IBT-NEXT: mv a0, zero +; RV32IBT-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IBT-NEXT: addi sp, sp, 16 +; RV32IBT-NEXT: ret +; +; RV64I-LABEL: func: +; RV64I: # %bb.0: # %entry +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: .cfi_def_cfa_offset 16 +; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: .cfi_offset ra, -8 +; RV64I-NEXT: lh a1, 0(a0) +; RV64I-NEXT: bltz a1, .LBB0_2 +; RV64I-NEXT: .LBB0_1: # %while.body +; RV64I-NEXT: # =>This Inner Loop Header: Depth=1 +; RV64I-NEXT: call f +; RV64I-NEXT: bnez a0, .LBB0_1 +; RV64I-NEXT: j .LBB0_3 +; RV64I-NEXT: .LBB0_2: # %while.body5 +; RV64I-NEXT: # =>This Inner Loop Header: Depth=1 +; RV64I-NEXT: call g +; RV64I-NEXT: bnez a0, .LBB0_2 +; RV64I-NEXT: .LBB0_3: # %return +; RV64I-NEXT: mv a0, zero +; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret +; +; RV64IBT-LABEL: func: +; RV64IBT: # %bb.0: # %entry +; RV64IBT-NEXT: addi sp, sp, -16 +; RV64IBT-NEXT: .cfi_def_cfa_offset 16 +; RV64IBT-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64IBT-NEXT: .cfi_offset ra, -8 +; RV64IBT-NEXT: lh a1, 0(a0) +; RV64IBT-NEXT: bltz a1, .LBB0_2 +; RV64IBT-NEXT: .LBB0_1: # %while.body +; RV64IBT-NEXT: # =>This Inner Loop Header: Depth=1 +; RV64IBT-NEXT: call f +; RV64IBT-NEXT: bnez a0, .LBB0_1 +; RV64IBT-NEXT: j .LBB0_3 +; RV64IBT-NEXT: .LBB0_2: # %while.body5 +; RV64IBT-NEXT: # =>This Inner Loop Header: Depth=1 +; RV64IBT-NEXT: call g +; RV64IBT-NEXT: bnez a0, .LBB0_2 +; RV64IBT-NEXT: .LBB0_3: # %return +; RV64IBT-NEXT: mv a0, zero +; RV64IBT-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64IBT-NEXT: addi sp, sp, 16 +; RV64IBT-NEXT: ret +entry: + %0 = load i16, i16* %a + %cmp = icmp sgt i16 %0, -1 + br i1 %cmp, label %while.body, label %while.body5 + +while.body: ; preds = %entry, %while.body + %a.addr.019 = phi i16* [ %1, %while.body ], [ %a, %entry ] + %call = tail call signext i32 bitcast (i32 (...)* @f to i32 (i16*)*)(i16* nonnull %a.addr.019) #2 + %conv2 = sext i32 %call to i64 + %1 = inttoptr i64 %conv2 to i16* + %tobool.not = icmp eq i32 %call, 0 + br i1 %tobool.not, label %return, label %while.body + +while.body5: ; preds = %entry, %while.body5 + %a.addr.117 = phi i16* [ %2, %while.body5 ], [ %a, %entry ] + %call6 = tail call signext i32 bitcast (i32 (...)* @g to i32 (i16*)*)(i16* nonnull %a.addr.117) #2 + %conv7 = sext i32 %call6 to i64 + %2 = inttoptr i64 %conv7 to i16* + %tobool4.not = icmp eq i32 %call6, 0 + br i1 %tobool4.not, label %return, label %while.body5 + +return: ; preds = %while.body5, %while.body + ret i16 undef +} + + +declare dso_local signext i32 @f(...) local_unnamed_addr #1 + +declare dso_local signext i32 @g(...) local_unnamed_addr #1