mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[RISCV] Remove RV64I SLLW/SRLW/SRAW patterns and add new test cases
As noted by Eli Friedman <https://reviews.llvm.org/D52977?id=168629#1315291>, the RV64I shift patterns for SLLW/SRLW/SRAW make some incorrect assumptions. SRAW assumed that (sext_inreg foo, i32) could only be produced when sign-extended an i32. However, it can be produced by input such as: define i64 @tricky_ashr(i64 %a, i64 %b) { %1 = shl i64 %a, 32 %2 = ashr i64 %1, 32 %3 = ashr i64 %2, %b ret i64 %3 } It's important not to select sraw in the above case, because sraw only uses bits lower 5 bits from the shift, while a shift of 32-63 would be valid. Similarly, the patterns for srlw assumed (and foo, 0xffffffff) would only be produced when zero-extending a value that was originally i32 in LLVM IR. This is obviously incorrect. This patch removes the SLLW/SRLW/SRAW shift patterns for the time being and adds test cases that would demonstrate a miscompile if the incorrect patterns were re-added. llvm-svn: 348067
This commit is contained in:
parent
5f2bf664d6
commit
272fa58228
@ -211,9 +211,6 @@ def immbottomxlenset : ImmLeaf<XLenVT, [{
|
||||
return countTrailingOnes<uint64_t>(Imm) >= 6;
|
||||
return countTrailingOnes<uint64_t>(Imm) >= 5;
|
||||
}]>;
|
||||
def immshifti32 : ImmLeaf<XLenVT, [{
|
||||
return countTrailingOnes<uint64_t>(Imm) >= 5;
|
||||
}]>;
|
||||
|
||||
// Addressing modes.
|
||||
// Necessary because a frameindex can't be matched directly in a pattern.
|
||||
@ -890,13 +887,6 @@ def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
|
||||
|
||||
/// RV64 patterns
|
||||
|
||||
def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{
|
||||
return cast<VTSDNode>(N->getOperand(1))->getVT() == MVT::i32;
|
||||
}]>;
|
||||
def zexti32 : PatFrags<(ops node:$src),
|
||||
[(and node:$src, 0xffffffff),
|
||||
(assertzexti32 node:$src)]>;
|
||||
|
||||
let Predicates = [IsRV64] in {
|
||||
|
||||
/// sext and zext
|
||||
@ -919,22 +909,7 @@ def : Pat<(sext_inreg (shl GPR:$rs1, uimm5:$shamt), i32),
|
||||
def : Pat<(sra (sext_inreg GPR:$rs1, i32), uimm5:$shamt),
|
||||
(SRAIW GPR:$rs1, uimm5:$shamt)>;
|
||||
|
||||
def : Pat<(sext_inreg (shl GPR:$rs1, GPR:$rs2), i32),
|
||||
(SLLW GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(sext_inreg (shl GPR:$rs1, (and GPR:$rs2, immshifti32)), i32),
|
||||
(SLLW GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(srl (zexti32 GPR:$rs1), GPR:$rs2),
|
||||
(SRLW GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(srl (zexti32 GPR:$rs1), (and GPR:$rs2, immshifti32)),
|
||||
(SRLW GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(sext_inreg (srl (zexti32 GPR:$rs1), GPR:$rs2), i32),
|
||||
(SRLW GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(sext_inreg (srl (zexti32 GPR:$rs1), (and GPR:$rs2, immshifti32)), i32),
|
||||
(SRLW GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(sra (sext_inreg GPR:$rs1, i32), GPR:$rs2),
|
||||
(SRAW GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(sra (sext_inreg GPR:$rs1, i32), (and GPR:$rs2, immshifti32)),
|
||||
(SRAW GPR:$rs1, GPR:$rs2)>;
|
||||
// TODO: patterns for SLLW/SRLW/SRAW.
|
||||
|
||||
/// Loads
|
||||
|
||||
|
@ -235,6 +235,8 @@ define i32 @xor(i32 %a, i32 %b) nounwind {
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
; TODO: should select srlw for RV64.
|
||||
|
||||
define i32 @srl(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: srl:
|
||||
; RV32I: # %bb.0:
|
||||
@ -243,12 +245,16 @@ define i32 @srl(i32 %a, i32 %b) nounwind {
|
||||
;
|
||||
; RV64I-LABEL: srl:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
; TODO: should select sraw for RV64.
|
||||
|
||||
define i32 @sra(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: sra:
|
||||
; RV32I: # %bb.0:
|
||||
@ -257,7 +263,8 @@ define i32 @sra(i32 %a, i32 %b) nounwind {
|
||||
;
|
||||
; RV64I-LABEL: sra:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
|
@ -444,10 +444,13 @@ define signext i32 @subw(i32 signext %a, i32 signext %b) {
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
; TODO: should select sllw for RV64.
|
||||
|
||||
define signext i32 @sllw(i32 signext %a, i32 zeroext %b) {
|
||||
; RV64I-LABEL: sllw:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV32I-LABEL: sllw:
|
||||
@ -458,10 +461,15 @@ define signext i32 @sllw(i32 signext %a, i32 zeroext %b) {
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
; TODO: should select srlw for RV64.
|
||||
|
||||
define signext i32 @srlw(i32 signext %a, i32 zeroext %b) {
|
||||
; RV64I-LABEL: srlw:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV32I-LABEL: srlw:
|
||||
@ -472,10 +480,13 @@ define signext i32 @srlw(i32 signext %a, i32 zeroext %b) {
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
; TODO: should select sraw for RV64.
|
||||
|
||||
define signext i32 @sraw(i64 %a, i32 zeroext %b) {
|
||||
; RV64I-LABEL: sraw:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV32I-LABEL: sraw:
|
||||
|
@ -624,12 +624,13 @@ define i32 @aext_sllw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
; Select sllw for all cases witha signext result.
|
||||
; TODO: Select sllw for all cases witha signext result.
|
||||
|
||||
define signext i32 @sext_sllw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: sext_sllw_aext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -638,7 +639,8 @@ define signext i32 @sext_sllw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
define signext i32 @sext_sllw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sllw_aext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -647,7 +649,8 @@ define signext i32 @sext_sllw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
define signext i32 @sext_sllw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sllw_aext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -656,7 +659,8 @@ define signext i32 @sext_sllw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
define signext i32 @sext_sllw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: sext_sllw_sext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -665,7 +669,8 @@ define signext i32 @sext_sllw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
define signext i32 @sext_sllw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sllw_sext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -674,7 +679,8 @@ define signext i32 @sext_sllw_sext_sext(i32 signext %a, i32 signext %b) nounwind
|
||||
define signext i32 @sext_sllw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sllw_sext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -683,7 +689,8 @@ define signext i32 @sext_sllw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind
|
||||
define signext i32 @sext_sllw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: sext_sllw_zext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -692,7 +699,8 @@ define signext i32 @sext_sllw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
define signext i32 @sext_sllw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sllw_zext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -701,7 +709,8 @@ define signext i32 @sext_sllw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind
|
||||
define signext i32 @sext_sllw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sllw_zext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sllw a0, a0, a1
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -808,12 +817,14 @@ define zeroext i32 @zext_sllw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
; srlw must always be selected for 32-bit lshr with variable arguments.
|
||||
; TODO: srlw should be selected for 32-bit lshr with variable arguments.
|
||||
|
||||
define i32 @aext_srlw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_srlw_aext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -822,7 +833,9 @@ define i32 @aext_srlw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
define i32 @aext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_srlw_aext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -831,7 +844,9 @@ define i32 @aext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
define i32 @aext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_srlw_aext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -840,7 +855,9 @@ define i32 @aext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
define i32 @aext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_srlw_sext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -849,7 +866,9 @@ define i32 @aext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
define i32 @aext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_srlw_sext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -858,7 +877,9 @@ define i32 @aext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
||||
define i32 @aext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_srlw_sext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -867,7 +888,7 @@ define i32 @aext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
||||
define i32 @aext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_srlw_zext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -876,7 +897,7 @@ define i32 @aext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
define i32 @aext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_srlw_zext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -885,7 +906,7 @@ define i32 @aext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
define i32 @aext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_srlw_zext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -894,7 +915,10 @@ define i32 @aext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
define signext i32 @sext_srlw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: sext_srlw_aext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -903,7 +927,10 @@ define signext i32 @sext_srlw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
define signext i32 @sext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: sext_srlw_aext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -912,7 +939,10 @@ define signext i32 @sext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
define signext i32 @sext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: sext_srlw_aext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -921,7 +951,10 @@ define signext i32 @sext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
define signext i32 @sext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: sext_srlw_sext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -930,7 +963,10 @@ define signext i32 @sext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
define signext i32 @sext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: sext_srlw_sext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -939,7 +975,10 @@ define signext i32 @sext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind
|
||||
define signext i32 @sext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: sext_srlw_sext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -948,7 +987,8 @@ define signext i32 @sext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind
|
||||
define signext i32 @sext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: sext_srlw_zext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -957,7 +997,8 @@ define signext i32 @sext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
define signext i32 @sext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: sext_srlw_zext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -966,7 +1007,8 @@ define signext i32 @sext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind
|
||||
define signext i32 @sext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: sext_srlw_zext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = lshr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -975,7 +1017,9 @@ define signext i32 @sext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind
|
||||
define zeroext i32 @zext_srlw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: zext_srlw_aext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -986,7 +1030,9 @@ define zeroext i32 @zext_srlw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
define zeroext i32 @zext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: zext_srlw_aext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -997,7 +1043,9 @@ define zeroext i32 @zext_srlw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
define zeroext i32 @zext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: zext_srlw_aext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1008,7 +1056,9 @@ define zeroext i32 @zext_srlw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
define zeroext i32 @zext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: zext_srlw_sext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1019,7 +1069,9 @@ define zeroext i32 @zext_srlw_sext_aext(i32 signext %a, i32 %b) nounwind {
|
||||
define zeroext i32 @zext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: zext_srlw_sext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1030,7 +1082,9 @@ define zeroext i32 @zext_srlw_sext_sext(i32 signext %a, i32 signext %b) nounwind
|
||||
define zeroext i32 @zext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: zext_srlw_sext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1041,7 +1095,7 @@ define zeroext i32 @zext_srlw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind
|
||||
define zeroext i32 @zext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: zext_srlw_zext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1052,7 +1106,7 @@ define zeroext i32 @zext_srlw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
define zeroext i32 @zext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: zext_srlw_zext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1063,7 +1117,7 @@ define zeroext i32 @zext_srlw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind
|
||||
define zeroext i32 @zext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: zext_srlw_zext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: srlw a0, a0, a1
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1071,12 +1125,14 @@ define zeroext i32 @zext_srlw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
; sraw must be selected if the first operand is not sign-extended.
|
||||
; TODO: sraw should be selected if the first operand is not sign-extended. If the
|
||||
; first operand is sign-extended, sra is equivalent for the test cases below.
|
||||
|
||||
define i32 @aext_sraw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_sraw_aext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1085,7 +1141,8 @@ define i32 @aext_sraw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
define i32 @aext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_sraw_aext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1094,7 +1151,8 @@ define i32 @aext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
define i32 @aext_sraw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_sraw_aext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1130,7 +1188,8 @@ define i32 @aext_sraw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind {
|
||||
define i32 @aext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: aext_sraw_zext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1139,7 +1198,8 @@ define i32 @aext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
define i32 @aext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: aext_sraw_zext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1148,7 +1208,8 @@ define i32 @aext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
define i32 @aext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: aext_sraw_zext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1157,7 +1218,8 @@ define i32 @aext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
define signext i32 @sext_sraw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: sext_sraw_aext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1166,7 +1228,8 @@ define signext i32 @sext_sraw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
define signext i32 @sext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sraw_aext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1175,7 +1238,8 @@ define signext i32 @sext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
define signext i32 @sext_sraw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sraw_aext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1211,7 +1275,8 @@ define signext i32 @sext_sraw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind
|
||||
define signext i32 @sext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: sext_sraw_zext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1220,7 +1285,8 @@ define signext i32 @sext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
define signext i32 @sext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sraw_zext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1229,7 +1295,8 @@ define signext i32 @sext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind
|
||||
define signext i32 @sext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: sext_sraw_zext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = ashr i32 %a, %b
|
||||
ret i32 %1
|
||||
@ -1238,7 +1305,8 @@ define signext i32 @sext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind
|
||||
define zeroext i32 @zext_sraw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: zext_sraw_aext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1249,7 +1317,8 @@ define zeroext i32 @zext_sraw_aext_aext(i32 %a, i32 %b) nounwind {
|
||||
define zeroext i32 @zext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: zext_sraw_aext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1260,7 +1329,8 @@ define zeroext i32 @zext_sraw_aext_sext(i32 %a, i32 signext %b) nounwind {
|
||||
define zeroext i32 @zext_sraw_aext_zext(i32 %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: zext_sraw_aext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1304,7 +1374,8 @@ define zeroext i32 @zext_sraw_sext_zext(i32 signext %a, i32 zeroext %b) nounwind
|
||||
define zeroext i32 @zext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: zext_sraw_zext_aext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1315,7 +1386,8 @@ define zeroext i32 @zext_sraw_zext_aext(i32 zeroext %a, i32 %b) nounwind {
|
||||
define zeroext i32 @zext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: zext_sraw_zext_sext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
@ -1326,7 +1398,8 @@ define zeroext i32 @zext_sraw_zext_sext(i32 zeroext %a, i32 signext %b) nounwind
|
||||
define zeroext i32 @zext_sraw_zext_zext(i32 zeroext %a, i32 zeroext %b) nounwind {
|
||||
; RV64I-LABEL: zext_sraw_zext_zext:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sraw a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: ret
|
||||
|
44
test/CodeGen/RISCV/rv64i-tricky-shifts.ll
Normal file
44
test/CodeGen/RISCV/rv64i-tricky-shifts.ll
Normal file
@ -0,0 +1,44 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64I
|
||||
|
||||
; These tests must not compile to sllw/srlw/sraw, as this would be semantically
|
||||
; incorrect in the case that %b holds a value between 32 and 63. Selection
|
||||
; patterns might make the mistake of assuming that a (sext_inreg foo, i32) can
|
||||
; only be produced when sign-extending an i32 type.
|
||||
|
||||
define i64 @tricky_shl(i64 %a, i64 %b) {
|
||||
; RV64I-LABEL: tricky_shl:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sll a0, a0, a1
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i64 %a, %b
|
||||
%2 = shl i64 %1, 32
|
||||
%3 = ashr i64 %2, 32
|
||||
ret i64 %3
|
||||
}
|
||||
|
||||
define i64 @tricky_lshr(i64 %a, i64 %b) {
|
||||
; RV64I-LABEL: tricky_lshr:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: srl a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = and i64 %a, 4294967295
|
||||
%2 = lshr i64 %1, %b
|
||||
ret i64 %2
|
||||
}
|
||||
|
||||
define i64 @tricky_ashr(i64 %a, i64 %b) {
|
||||
; RV64I-LABEL: tricky_ashr:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: sext.w a0, a0
|
||||
; RV64I-NEXT: sra a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
%1 = shl i64 %a, 32
|
||||
%2 = ashr i64 %1, 32
|
||||
%3 = ashr i64 %2, %b
|
||||
ret i64 %3
|
||||
}
|
Loading…
Reference in New Issue
Block a user