Skip to content

Commit

Permalink
[LoongArch][ISel] Check the number of sign bits in PatGprGpr_32 (#…
Browse files Browse the repository at this point in the history
…107432)

After #92205, LoongArch ISel
selects `div.w` for `trunc i64 (sdiv i64 3202030857, (sext i32 X to
i64)) to i32`. It is incorrect since `3202030857` is not a signed 32-bit
constant. It will produce wrong result when `X == 2`:
https://alive2.llvm.org/ce/z/pzfGZZ

This patch adds additional `sexti32` checks to operands of
`PatGprGpr_32`.
Alive2 proof: https://alive2.llvm.org/ce/z/AkH5Mp

Fix #107414.

(cherry picked from commit a111f91)
  • Loading branch information
dtcxzyw authored and tru committed Sep 16, 2024
1 parent f0010d1 commit 78654fa
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
5 changes: 4 additions & 1 deletion llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1065,10 +1065,13 @@ def RDTIME_D : RDTIME_2R<0x00006800>;

/// Generic pattern classes

def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
}]>;
class PatGprGpr<SDPatternOperator OpNode, LAInst Inst>
: Pat<(OpNode GPR:$rj, GPR:$rk), (Inst GPR:$rj, GPR:$rk)>;
class PatGprGpr_32<SDPatternOperator OpNode, LAInst Inst>
: Pat<(sext_inreg (OpNode GPR:$rj, GPR:$rk), i32), (Inst GPR:$rj, GPR:$rk)>;
: Pat<(sext_inreg (OpNode (assertsexti32 GPR:$rj), (assertsexti32 GPR:$rk)), i32), (Inst GPR:$rj, GPR:$rk)>;
class PatGpr<SDPatternOperator OpNode, LAInst Inst>
: Pat<(OpNode GPR:$rj), (Inst GPR:$rj)>;

Expand Down
67 changes: 65 additions & 2 deletions llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ define signext i32 @sdiv_si32_ui32_ui32(i32 %a, i32 %b) {
; LA64: # %bb.0: # %entry
; LA64-NEXT: addi.w $a1, $a1, 0
; LA64-NEXT: addi.w $a0, $a0, 0
; LA64-NEXT: div.w $a0, $a0, $a1
; LA64-NEXT: div.d $a0, $a0, $a1
; LA64-NEXT: addi.w $a0, $a0, 0
; LA64-NEXT: ret
;
; LA32-TRAP-LABEL: sdiv_si32_ui32_ui32:
Expand All @@ -207,11 +208,12 @@ define signext i32 @sdiv_si32_ui32_ui32(i32 %a, i32 %b) {
; LA64-TRAP: # %bb.0: # %entry
; LA64-TRAP-NEXT: addi.w $a1, $a1, 0
; LA64-TRAP-NEXT: addi.w $a0, $a0, 0
; LA64-TRAP-NEXT: div.w $a0, $a0, $a1
; LA64-TRAP-NEXT: div.d $a0, $a0, $a1
; LA64-TRAP-NEXT: bnez $a1, .LBB5_2
; LA64-TRAP-NEXT: # %bb.1: # %entry
; LA64-TRAP-NEXT: break 7
; LA64-TRAP-NEXT: .LBB5_2: # %entry
; LA64-TRAP-NEXT: addi.w $a0, $a0, 0
; LA64-TRAP-NEXT: ret
entry:
%r = sdiv i32 %a, %b
Expand Down Expand Up @@ -1151,3 +1153,64 @@ entry:
%r = urem i64 %a, %b
ret i64 %r
}

define signext i32 @pr107414(i32 signext %x) {
; LA32-LABEL: pr107414:
; LA32: # %bb.0: # %entry
; LA32-NEXT: addi.w $sp, $sp, -16
; LA32-NEXT: .cfi_def_cfa_offset 16
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
; LA32-NEXT: .cfi_offset 1, -4
; LA32-NEXT: move $a2, $a0
; LA32-NEXT: srai.w $a3, $a0, 31
; LA32-NEXT: lu12i.w $a0, -266831
; LA32-NEXT: ori $a0, $a0, 3337
; LA32-NEXT: move $a1, $zero
; LA32-NEXT: bl %plt(__divdi3)
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
; LA32-NEXT: addi.w $sp, $sp, 16
; LA32-NEXT: ret
;
; LA64-LABEL: pr107414:
; LA64: # %bb.0: # %entry
; LA64-NEXT: lu12i.w $a1, -266831
; LA64-NEXT: ori $a1, $a1, 3337
; LA64-NEXT: lu32i.d $a1, 0
; LA64-NEXT: div.d $a0, $a1, $a0
; LA64-NEXT: addi.w $a0, $a0, 0
; LA64-NEXT: ret
;
; LA32-TRAP-LABEL: pr107414:
; LA32-TRAP: # %bb.0: # %entry
; LA32-TRAP-NEXT: addi.w $sp, $sp, -16
; LA32-TRAP-NEXT: .cfi_def_cfa_offset 16
; LA32-TRAP-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
; LA32-TRAP-NEXT: .cfi_offset 1, -4
; LA32-TRAP-NEXT: move $a2, $a0
; LA32-TRAP-NEXT: srai.w $a3, $a0, 31
; LA32-TRAP-NEXT: lu12i.w $a0, -266831
; LA32-TRAP-NEXT: ori $a0, $a0, 3337
; LA32-TRAP-NEXT: move $a1, $zero
; LA32-TRAP-NEXT: bl %plt(__divdi3)
; LA32-TRAP-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
; LA32-TRAP-NEXT: addi.w $sp, $sp, 16
; LA32-TRAP-NEXT: ret
;
; LA64-TRAP-LABEL: pr107414:
; LA64-TRAP: # %bb.0: # %entry
; LA64-TRAP-NEXT: lu12i.w $a1, -266831
; LA64-TRAP-NEXT: ori $a1, $a1, 3337
; LA64-TRAP-NEXT: lu32i.d $a1, 0
; LA64-TRAP-NEXT: div.d $a1, $a1, $a0
; LA64-TRAP-NEXT: bnez $a0, .LBB32_2
; LA64-TRAP-NEXT: # %bb.1: # %entry
; LA64-TRAP-NEXT: break 7
; LA64-TRAP-NEXT: .LBB32_2: # %entry
; LA64-TRAP-NEXT: addi.w $a0, $a1, 0
; LA64-TRAP-NEXT: ret
entry:
%conv = sext i32 %x to i64
%div = sdiv i64 3202030857, %conv
%conv1 = trunc i64 %div to i32
ret i32 %conv1
}

0 comments on commit 78654fa

Please sign in to comment.