forked from OSchip/llvm-project
[RISCV] Custom legalize i32 operations for RV64 to reduce signed extensions
Differential Revision: https://reviews.llvm.org/D65434 llvm-svn: 367960
This commit is contained in:
parent
f0380bac5f
commit
b12056bd33
|
@ -100,6 +100,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|||
setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand);
|
||||
|
||||
if (Subtarget.is64Bit()) {
|
||||
setOperationAction(ISD::ADD, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SUB, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SHL, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SRA, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SRL, MVT::i32, Custom);
|
||||
|
@ -116,6 +118,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|||
}
|
||||
|
||||
if (Subtarget.is64Bit() && Subtarget.hasStdExtM()) {
|
||||
setOperationAction(ISD::MUL, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SDIV, MVT::i32, Custom);
|
||||
setOperationAction(ISD::UDIV, MVT::i32, Custom);
|
||||
setOperationAction(ISD::UREM, MVT::i32, Custom);
|
||||
|
@ -834,6 +837,18 @@ static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG) {
|
|||
return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewRes);
|
||||
}
|
||||
|
||||
// Converts the given 32-bit operation to a i64 operation with signed extension
|
||||
// semantic to reduce the signed extension instructions.
|
||||
static SDValue customLegalizeToWOpWithSExt(SDNode *N, SelectionDAG &DAG) {
|
||||
SDLoc DL(N);
|
||||
SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(0));
|
||||
SDValue NewOp1 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
|
||||
SDValue NewWOp = DAG.getNode(N->getOpcode(), DL, MVT::i64, NewOp0, NewOp1);
|
||||
SDValue NewRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, MVT::i64, NewWOp,
|
||||
DAG.getValueType(MVT::i32));
|
||||
return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewRes);
|
||||
}
|
||||
|
||||
void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
|
||||
SmallVectorImpl<SDValue> &Results,
|
||||
SelectionDAG &DAG) const {
|
||||
|
@ -854,6 +869,15 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
|
|||
Results.push_back(RCW.getValue(2));
|
||||
break;
|
||||
}
|
||||
case ISD::ADD:
|
||||
case ISD::SUB:
|
||||
case ISD::MUL:
|
||||
assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
|
||||
"Unexpected custom legalisation");
|
||||
if (N->getOperand(1).getOpcode() == ISD::Constant)
|
||||
return;
|
||||
Results.push_back(customLegalizeToWOpWithSExt(N, DAG));
|
||||
break;
|
||||
case ISD::SHL:
|
||||
case ISD::SRA:
|
||||
case ISD::SRL:
|
||||
|
|
|
@ -153,7 +153,7 @@ define i32 @add(i32 %a, i32 %b) nounwind {
|
|||
;
|
||||
; RV64I-LABEL: add:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -167,7 +167,7 @@ define i32 @sub(i32 %a, i32 %b) nounwind {
|
|||
;
|
||||
; RV64I-LABEL: sub:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
|
|
@ -63,7 +63,7 @@ define i32 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i128 %d, i32 %e, i32 %f,
|
|||
; RV64I-NEXT: add a0, a0, a5
|
||||
; RV64I-NEXT: add a0, a0, a6
|
||||
; RV64I-NEXT: lw a1, 8(sp)
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%a_ext = zext i8 %a to i32
|
||||
%b_ext = zext i16 %b to i32
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
define i32 @aext_addw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_addw_aext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -20,7 +20,7 @@ define i32 @aext_addw_aext_aext(i32 %a, i32 %b) nounwind {
|
|||
define i32 @aext_addw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_addw_aext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -29,7 +29,7 @@ define i32 @aext_addw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
|||
define i32 @aext_addw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_addw_aext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -38,7 +38,7 @@ define i32 @aext_addw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
|||
define i32 @aext_addw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_addw_sext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -47,7 +47,7 @@ define i32 @aext_addw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
|||
define i32 @aext_addw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_addw_sext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -56,7 +56,7 @@ define i32 @aext_addw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
|||
define i32 @aext_addw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_addw_sext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -65,7 +65,7 @@ define i32 @aext_addw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
|||
define i32 @aext_addw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_addw_zext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -74,7 +74,7 @@ define i32 @aext_addw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
|||
define i32 @aext_addw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_addw_zext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -83,7 +83,7 @@ define i32 @aext_addw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
|||
define i32 @aext_addw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_addw_zext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: add a0, a0, a1
|
||||
; RV64I-NEXT: addw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = add i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -279,7 +279,7 @@ define zeroext i32 @zext_addw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind
|
|||
define i32 @aext_subw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_subw_aext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -288,7 +288,7 @@ define i32 @aext_subw_aext_aext(i32 %a, i32 %b) nounwind {
|
|||
define i32 @aext_subw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_subw_aext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -297,7 +297,7 @@ define i32 @aext_subw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
|||
define i32 @aext_subw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_subw_aext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -306,7 +306,7 @@ define i32 @aext_subw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
|||
define i32 @aext_subw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_subw_sext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -315,7 +315,7 @@ define i32 @aext_subw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
|||
define i32 @aext_subw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_subw_sext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -324,7 +324,7 @@ define i32 @aext_subw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
|||
define i32 @aext_subw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_subw_sext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -333,7 +333,7 @@ define i32 @aext_subw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
|||
define i32 @aext_subw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_subw_zext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -342,7 +342,7 @@ define i32 @aext_subw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
|||
define i32 @aext_subw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_subw_zext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -351,7 +351,7 @@ define i32 @aext_subw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
|||
define i32 @aext_subw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_subw_zext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sub a0, a0, a1
|
||||
; RV64I-NEXT: subw a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = sub i32 %a, %b
|
||||
ret i32 %1
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s | FileCheck %s
|
||||
|
||||
define signext i32 @addw(i32 signext %s, i32 signext %n, i32 signext %k) nounwind {
|
||||
; CHECK-LABEL: addw:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: bge a0, a1, .LBB0_2
|
||||
; CHECK-NEXT: # %bb.1: # %for.body.preheader
|
||||
; CHECK-NEXT: not a2, a0
|
||||
; CHECK-NEXT: add a2, a2, a1
|
||||
; CHECK-NEXT: sub a1, a1, a0
|
||||
; CHECK-NEXT: addi a1, a1, -2
|
||||
; CHECK-NEXT: slli a1, a1, 32
|
||||
; CHECK-NEXT: srli a1, a1, 32
|
||||
; CHECK-NEXT: slli a3, a2, 32
|
||||
; CHECK-NEXT: srli a3, a3, 32
|
||||
; CHECK-NEXT: mul a1, a3, a1
|
||||
; CHECK-NEXT: addi a3, a0, 1
|
||||
; CHECK-NEXT: mul a2, a2, a3
|
||||
; CHECK-NEXT: add a0, a2, a0
|
||||
; CHECK-NEXT: srli a1, a1, 1
|
||||
; CHECK-NEXT: addw a0, a0, a1
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-NEXT: .LBB0_2:
|
||||
; CHECK-NEXT: mv a0, zero
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
%cmp6 = icmp slt i32 %s, %n
|
||||
br i1 %cmp6, label %for.body.preheader, label %for.cond.cleanup
|
||||
|
||||
for.body.preheader: ; preds = %entry
|
||||
%0 = xor i32 %s, -1
|
||||
%1 = add i32 %0, %n
|
||||
%2 = add i32 %s, 1
|
||||
%3 = mul i32 %1, %2
|
||||
%4 = zext i32 %1 to i33
|
||||
%5 = add i32 %n, -2
|
||||
%6 = sub i32 %5, %s
|
||||
%7 = zext i32 %6 to i33
|
||||
%8 = mul i33 %4, %7
|
||||
%9 = lshr i33 %8, 1
|
||||
%10 = trunc i33 %9 to i32
|
||||
%11 = add i32 %3, %s
|
||||
%12 = add i32 %11, %10
|
||||
br label %for.cond.cleanup
|
||||
|
||||
for.cond.cleanup: ; preds = %for.body.preheader, %entry
|
||||
%sum.0.lcssa = phi i32 [ 0, %entry ], [ %12, %for.body.preheader ]
|
||||
ret i32 %sum.0.lcssa
|
||||
}
|
||||
|
||||
define signext i32 @subw(i32 signext %s, i32 signext %n, i32 signext %k) nounwind {
|
||||
; CHECK-LABEL: subw:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: bge a0, a1, .LBB1_2
|
||||
; CHECK-NEXT: # %bb.1: # %for.body.preheader
|
||||
; CHECK-NEXT: sub a2, a1, a0
|
||||
; CHECK-NEXT: addi a2, a2, -2
|
||||
; CHECK-NEXT: slli a2, a2, 32
|
||||
; CHECK-NEXT: srli a2, a2, 32
|
||||
; CHECK-NEXT: not a3, a0
|
||||
; CHECK-NEXT: add a1, a3, a1
|
||||
; CHECK-NEXT: slli a4, a1, 32
|
||||
; CHECK-NEXT: srli a4, a4, 32
|
||||
; CHECK-NEXT: mul a2, a4, a2
|
||||
; CHECK-NEXT: mul a1, a1, a3
|
||||
; CHECK-NEXT: sub a0, a1, a0
|
||||
; CHECK-NEXT: srli a1, a2, 1
|
||||
; CHECK-NEXT: subw a0, a0, a1
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-NEXT: .LBB1_2:
|
||||
; CHECK-NEXT: mv a0, zero
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
%cmp6 = icmp slt i32 %s, %n
|
||||
br i1 %cmp6, label %for.body.preheader, label %for.cond.cleanup
|
||||
|
||||
for.body.preheader: ; preds = %entry
|
||||
%0 = xor i32 %s, -1
|
||||
%1 = add i32 %0, %n
|
||||
%2 = xor i32 %s, -1
|
||||
%3 = mul i32 %1, %2
|
||||
%4 = zext i32 %1 to i33
|
||||
%5 = add i32 %n, -2
|
||||
%6 = sub i32 %5, %s
|
||||
%7 = zext i32 %6 to i33
|
||||
%8 = mul i33 %4, %7
|
||||
%9 = lshr i33 %8, 1
|
||||
%10 = trunc i33 %9 to i32
|
||||
%11 = sub i32 %3, %s
|
||||
%12 = sub i32 %11, %10
|
||||
br label %for.cond.cleanup
|
||||
|
||||
for.cond.cleanup: ; preds = %for.body.preheader, %entry
|
||||
%sum.0.lcssa = phi i32 [ 0, %entry ], [ %12, %for.body.preheader ]
|
||||
ret i32 %sum.0.lcssa
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
define i32 @aext_mulw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64IM-LABEL: aext_mulw_aext_aext:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: mul a0, a0, a1
|
||||
; RV64IM-NEXT: mulw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = mul i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -18,7 +18,7 @@ define i32 @aext_mulw_aext_aext(i32 %a, i32 %b) nounwind {
|
|||
define i32 @aext_mulw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64IM-LABEL: aext_mulw_aext_sext:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: mul a0, a0, a1
|
||||
; RV64IM-NEXT: mulw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = mul i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -27,7 +27,7 @@ define i32 @aext_mulw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
|||
define i32 @aext_mulw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64IM-LABEL: aext_mulw_aext_zext:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: mul a0, a0, a1
|
||||
; RV64IM-NEXT: mulw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = mul i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -36,7 +36,7 @@ define i32 @aext_mulw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
|||
define i32 @aext_mulw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
; RV64IM-LABEL: aext_mulw_sext_aext:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: mul a0, a0, a1
|
||||
; RV64IM-NEXT: mulw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = mul i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -45,7 +45,7 @@ define i32 @aext_mulw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
|||
define i32 @aext_mulw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64IM-LABEL: aext_mulw_sext_sext:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: mul a0, a0, a1
|
||||
; RV64IM-NEXT: mulw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = mul i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -54,7 +54,7 @@ define i32 @aext_mulw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
|||
define i32 @aext_mulw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
||||
; RV64IM-LABEL: aext_mulw_sext_zext:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: mul a0, a0, a1
|
||||
; RV64IM-NEXT: mulw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = mul i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -63,7 +63,7 @@ define i32 @aext_mulw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
|||
define i32 @aext_mulw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64IM-LABEL: aext_mulw_zext_aext:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: mul a0, a0, a1
|
||||
; RV64IM-NEXT: mulw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = mul i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -72,7 +72,7 @@ define i32 @aext_mulw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
|||
define i32 @aext_mulw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64IM-LABEL: aext_mulw_zext_sext:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: mul a0, a0, a1
|
||||
; RV64IM-NEXT: mulw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = mul i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -81,7 +81,7 @@ define i32 @aext_mulw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
|||
define i32 @aext_mulw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64IM-LABEL: aext_mulw_zext_zext:
|
||||
; RV64IM: # %bb.0:
|
||||
; RV64IM-NEXT: mul a0, a0, a1
|
||||
; RV64IM-NEXT: mulw a0, a0, a1
|
||||
; RV64IM-NEXT: ret
|
||||
%1 = mul i32 %a, %b
|
||||
ret i32 %1
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s | FileCheck %s
|
||||
|
||||
define signext i32 @mulw(i32 signext %s, i32 signext %n, i32 signext %k) nounwind {
|
||||
; CHECK-LABEL: mulw:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: addi a2, zero, 1
|
||||
; CHECK-NEXT: bge a0, a1, .LBB0_3
|
||||
; CHECK-NEXT: # %bb.1: # %for.body.preheader
|
||||
; CHECK-NEXT: addi a2, zero, 1
|
||||
; CHECK-NEXT: .LBB0_2: # %for.body
|
||||
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: mulw a2, a0, a2
|
||||
; CHECK-NEXT: addiw a0, a0, 1
|
||||
; CHECK-NEXT: blt a0, a1, .LBB0_2
|
||||
; CHECK-NEXT: .LBB0_3: # %for.cond.cleanup
|
||||
; CHECK-NEXT: mv a0, a2
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
%cmp6 = icmp slt i32 %s, %n
|
||||
br i1 %cmp6, label %for.body, label %for.cond.cleanup
|
||||
|
||||
for.cond.cleanup: ; preds = %for.body, %entry
|
||||
%sum.0.lcssa = phi i32 [ 1, %entry ], [ %mul, %for.body ]
|
||||
ret i32 %sum.0.lcssa
|
||||
|
||||
for.body: ; preds = %entry, %for.body
|
||||
%i.08 = phi i32 [ %inc, %for.body ], [ %s, %entry ]
|
||||
%sum.07 = phi i32 [ %mul, %for.body ], [ 1, %entry ]
|
||||
%mul = mul nsw i32 %i.08, %sum.07
|
||||
%inc = add nsw i32 %i.08, 1
|
||||
%cmp = icmp slt i32 %inc, %n
|
||||
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
||||
}
|
|
@ -257,7 +257,7 @@ define i32 @cmovccdep(i32 signext %a, i32 %b, i32 %c, i32 %d) nounwind {
|
|||
; RV64I-NEXT: mv a2, a1
|
||||
; RV64I-NEXT: bne a0, a4, .LBB6_4
|
||||
; RV64I-NEXT: .LBB6_2: # %entry
|
||||
; RV64I-NEXT: add a0, a1, a2
|
||||
; RV64I-NEXT: addw a0, a1, a2
|
||||
; RV64I-NEXT: ret
|
||||
; RV64I-NEXT: .LBB6_3: # %entry
|
||||
; RV64I-NEXT: mv a1, a2
|
||||
|
@ -265,7 +265,7 @@ define i32 @cmovccdep(i32 signext %a, i32 %b, i32 %c, i32 %d) nounwind {
|
|||
; RV64I-NEXT: beq a0, a4, .LBB6_2
|
||||
; RV64I-NEXT: .LBB6_4: # %entry
|
||||
; RV64I-NEXT: mv a2, a3
|
||||
; RV64I-NEXT: add a0, a1, a2
|
||||
; RV64I-NEXT: addw a0, a1, a2
|
||||
; RV64I-NEXT: ret
|
||||
entry:
|
||||
%cmp = icmp eq i32 %a, 123
|
||||
|
@ -305,7 +305,7 @@ define i32 @cmovdiffcc(i1 %a, i1 %b, i32 %c, i32 %d, i32 %e, i32 %f) nounwind {
|
|||
; RV64I-NEXT: andi a0, a0, 1
|
||||
; RV64I-NEXT: beqz a0, .LBB7_4
|
||||
; RV64I-NEXT: .LBB7_2: # %entry
|
||||
; RV64I-NEXT: add a0, a2, a4
|
||||
; RV64I-NEXT: addw a0, a2, a4
|
||||
; RV64I-NEXT: ret
|
||||
; RV64I-NEXT: .LBB7_3: # %entry
|
||||
; RV64I-NEXT: mv a4, a5
|
||||
|
@ -313,7 +313,7 @@ define i32 @cmovdiffcc(i1 %a, i1 %b, i32 %c, i32 %d, i32 %e, i32 %f) nounwind {
|
|||
; RV64I-NEXT: bnez a0, .LBB7_2
|
||||
; RV64I-NEXT: .LBB7_4: # %entry
|
||||
; RV64I-NEXT: mv a2, a3
|
||||
; RV64I-NEXT: add a0, a2, a4
|
||||
; RV64I-NEXT: addw a0, a2, a4
|
||||
; RV64I-NEXT: ret
|
||||
entry:
|
||||
%cond1 = select i1 %a, i32 %c, i32 %d
|
||||
|
|
|
@ -1320,7 +1320,7 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind {
|
|||
; LP64-LP64F-LP64D-FPELIM-NEXT: add a1, a1, s0
|
||||
; LP64-LP64F-LP64D-FPELIM-NEXT: add a1, a1, a2
|
||||
; LP64-LP64F-LP64D-FPELIM-NEXT: ld a0, 0(a0)
|
||||
; LP64-LP64F-LP64D-FPELIM-NEXT: add a0, a1, a0
|
||||
; LP64-LP64F-LP64D-FPELIM-NEXT: addw a0, a1, a0
|
||||
; LP64-LP64F-LP64D-FPELIM-NEXT: ld s0, 16(sp)
|
||||
; LP64-LP64F-LP64D-FPELIM-NEXT: ld ra, 24(sp)
|
||||
; LP64-LP64F-LP64D-FPELIM-NEXT: addi sp, sp, 96
|
||||
|
@ -1364,7 +1364,7 @@ define i32 @va4_va_copy(i32 %argno, ...) nounwind {
|
|||
; LP64-LP64F-LP64D-WITHFP-NEXT: add a1, a1, s1
|
||||
; LP64-LP64F-LP64D-WITHFP-NEXT: add a1, a1, a2
|
||||
; LP64-LP64F-LP64D-WITHFP-NEXT: ld a0, 0(a0)
|
||||
; LP64-LP64F-LP64D-WITHFP-NEXT: add a0, a1, a0
|
||||
; LP64-LP64F-LP64D-WITHFP-NEXT: addw a0, a1, a0
|
||||
; LP64-LP64F-LP64D-WITHFP-NEXT: ld s1, 24(sp)
|
||||
; LP64-LP64F-LP64D-WITHFP-NEXT: ld s0, 32(sp)
|
||||
; LP64-LP64F-LP64D-WITHFP-NEXT: ld ra, 40(sp)
|
||||
|
|
Loading…
Reference in New Issue