Skip to content

Commit

Permalink
[Mips] In LowerShift*Parts, xor with bits-1 instead of -1.
Browse files Browse the repository at this point in the history
If we start with an i128 shift, the initial shift amount would
usually have zeros in bit 8 and above. xoring the shift amount with
-1 will set those upper bits to 1. If DAGCombiner is able to prove those
bits are now 1, then the shift that uses the xor will be replaced
with undef. Which we don't want.

Reduce the xor constant to VT.bits-1 where VT is half the size of
the larger shift type. This avoids toggling the upper bits. The
hardware shift instruction only uses the lower bits of the shift
amount. I assume the code used NOT because the hardware doesn't
use the upper bits, but that isn't compatible with the LLVM poison
semantics.

Fixes llvm#71142.
  • Loading branch information
topperc committed Nov 3, 2023
1 parent ae49bf5 commit 3dff0e6
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 44 deletions.
14 changes: 8 additions & 6 deletions llvm/lib/Target/Mips/MipsISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2593,12 +2593,13 @@ SDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op,
SDValue Shamt = Op.getOperand(2);
// if shamt < (VT.bits):
// lo = (shl lo, shamt)
// hi = (or (shl hi, shamt) (srl (srl lo, 1), ~shamt))
// hi = (or (shl hi, shamt) (srl (srl lo, 1), (VT.bits-1) ^ shamt))
// else:
// lo = 0
// hi = (shl lo, shamt[4:0])
SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
DAG.getConstant(-1, DL, MVT::i32));
SDValue Not =
DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
DAG.getConstant(VT.getSizeInBits() - 1, DL, MVT::i32));
SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo,
DAG.getConstant(1, DL, VT));
SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, Not);
Expand All @@ -2623,7 +2624,7 @@ SDValue MipsTargetLowering::lowerShiftRightParts(SDValue Op, SelectionDAG &DAG,
MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;

// if shamt < (VT.bits):
// lo = (or (shl (shl hi, 1), ~shamt) (srl lo, shamt))
// lo = (or (shl (shl hi, 1), (VT.bits-1) ^ shamt) (srl lo, shamt))
// if isSRA:
// hi = (sra hi, shamt)
// else:
Expand All @@ -2635,8 +2636,9 @@ SDValue MipsTargetLowering::lowerShiftRightParts(SDValue Op, SelectionDAG &DAG,
// else:
// lo = (srl hi, shamt[4:0])
// hi = 0
SDValue Not = DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
DAG.getConstant(-1, DL, MVT::i32));
SDValue Not =
DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,
DAG.getConstant(VT.getSizeInBits() - 1, DL, MVT::i32));
SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, VT, Hi,
DAG.getConstant(1, DL, VT));
SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, ShiftLeft1Hi, Not);
Expand Down
24 changes: 12 additions & 12 deletions llvm/test/CodeGen/Mips/llvm-ir/ashr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ define signext i64 @ashr_i64(i64 signext %a, i64 signext %b) {
; MIPS-NEXT: srav $3, $4, $7
; MIPS-NEXT: # %bb.1: # %entry
; MIPS-NEXT: srlv $1, $5, $7
; MIPS-NEXT: not $2, $7
; MIPS-NEXT: xori $2, $7, 31
; MIPS-NEXT: sll $4, $4, 1
; MIPS-NEXT: sllv $2, $4, $2
; MIPS-NEXT: or $1, $2, $1
Expand All @@ -294,7 +294,7 @@ define signext i64 @ashr_i64(i64 signext %a, i64 signext %b) {
; MIPS32-LABEL: ashr_i64:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: srlv $1, $5, $7
; MIPS32-NEXT: not $2, $7
; MIPS32-NEXT: xori $2, $7, 31
; MIPS32-NEXT: sll $3, $4, 1
; MIPS32-NEXT: sllv $2, $3, $2
; MIPS32-NEXT: or $3, $2, $1
Expand All @@ -308,7 +308,7 @@ define signext i64 @ashr_i64(i64 signext %a, i64 signext %b) {
; 32R2-LABEL: ashr_i64:
; 32R2: # %bb.0: # %entry
; 32R2-NEXT: srlv $1, $5, $7
; 32R2-NEXT: not $2, $7
; 32R2-NEXT: xori $2, $7, 31
; 32R2-NEXT: sll $3, $4, 1
; 32R2-NEXT: sllv $2, $3, $2
; 32R2-NEXT: or $3, $2, $1
Expand All @@ -328,7 +328,7 @@ define signext i64 @ashr_i64(i64 signext %a, i64 signext %b) {
; 32R6-NEXT: selnez $6, $6, $3
; 32R6-NEXT: or $2, $6, $2
; 32R6-NEXT: srlv $5, $5, $7
; 32R6-NEXT: not $6, $7
; 32R6-NEXT: xori $6, $7, 31
; 32R6-NEXT: sll $4, $4, 1
; 32R6-NEXT: sllv $4, $4, $6
; 32R6-NEXT: or $4, $4, $5
Expand Down Expand Up @@ -360,9 +360,9 @@ define signext i64 @ashr_i64(i64 signext %a, i64 signext %b) {
; MMR3-LABEL: ashr_i64:
; MMR3: # %bb.0: # %entry
; MMR3-NEXT: srlv $2, $5, $7
; MMR3-NEXT: not16 $3, $7
; MMR3-NEXT: sll16 $5, $4, 1
; MMR3-NEXT: sllv $3, $5, $3
; MMR3-NEXT: xori $1, $7, 31
; MMR3-NEXT: sll16 $3, $4, 1
; MMR3-NEXT: sllv $3, $3, $1
; MMR3-NEXT: or16 $3, $2
; MMR3-NEXT: srav $2, $4, $7
; MMR3-NEXT: andi16 $5, $7, 32
Expand All @@ -380,7 +380,7 @@ define signext i64 @ashr_i64(i64 signext %a, i64 signext %b) {
; MMR6-NEXT: selnez $6, $6, $3
; MMR6-NEXT: or $2, $6, $2
; MMR6-NEXT: srlv $5, $5, $7
; MMR6-NEXT: not16 $6, $7
; MMR6-NEXT: xori $6, $7, 31
; MMR6-NEXT: sll16 $4, $4, 1
; MMR6-NEXT: sllv $4, $4, $6
; MMR6-NEXT: or $4, $4, $5
Expand Down Expand Up @@ -609,7 +609,7 @@ define signext i128 @ashr_i128(i128 signext %a, i128 signext %b) {
; MIPS3-NEXT: # %bb.1: # %entry
; MIPS3-NEXT: dsrlv $1, $5, $7
; MIPS3-NEXT: dsll $4, $4, 1
; MIPS3-NEXT: not $2, $2
; MIPS3-NEXT: xori $2, $2, 63
; MIPS3-NEXT: dsllv $2, $4, $2
; MIPS3-NEXT: or $1, $2, $1
; MIPS3-NEXT: move $2, $3
Expand All @@ -624,7 +624,7 @@ define signext i128 @ashr_i128(i128 signext %a, i128 signext %b) {
; MIPS64-NEXT: dsrlv $1, $5, $7
; MIPS64-NEXT: dsll $2, $4, 1
; MIPS64-NEXT: sll $5, $7, 0
; MIPS64-NEXT: not $3, $5
; MIPS64-NEXT: xori $3, $5, 63
; MIPS64-NEXT: dsllv $2, $2, $3
; MIPS64-NEXT: or $3, $2, $1
; MIPS64-NEXT: dsrav $2, $4, $7
Expand All @@ -639,7 +639,7 @@ define signext i128 @ashr_i128(i128 signext %a, i128 signext %b) {
; MIPS64R2-NEXT: dsrlv $1, $5, $7
; MIPS64R2-NEXT: dsll $2, $4, 1
; MIPS64R2-NEXT: sll $5, $7, 0
; MIPS64R2-NEXT: not $3, $5
; MIPS64R2-NEXT: xori $3, $5, 63
; MIPS64R2-NEXT: dsllv $2, $2, $3
; MIPS64R2-NEXT: or $3, $2, $1
; MIPS64R2-NEXT: dsrav $2, $4, $7
Expand All @@ -661,7 +661,7 @@ define signext i128 @ashr_i128(i128 signext %a, i128 signext %b) {
; MIPS64R6-NEXT: or $2, $8, $2
; MIPS64R6-NEXT: dsrlv $5, $5, $7
; MIPS64R6-NEXT: dsll $4, $4, 1
; MIPS64R6-NEXT: not $3, $3
; MIPS64R6-NEXT: xori $3, $3, 63
; MIPS64R6-NEXT: dsllv $3, $4, $3
; MIPS64R6-NEXT: or $3, $3, $5
; MIPS64R6-NEXT: seleqz $3, $3, $6
Expand Down
26 changes: 13 additions & 13 deletions llvm/test/CodeGen/Mips/llvm-ir/lshr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ define signext i64 @lshr_i64(i64 signext %a, i64 signext %b) {
; MIPS2-NEXT: addiu $2, $zero, 0
; MIPS2-NEXT: # %bb.1: # %entry
; MIPS2-NEXT: srlv $1, $5, $7
; MIPS2-NEXT: not $2, $7
; MIPS2-NEXT: xori $2, $7, 31
; MIPS2-NEXT: sll $3, $4, 1
; MIPS2-NEXT: sllv $2, $3, $2
; MIPS2-NEXT: or $3, $2, $1
Expand All @@ -296,7 +296,7 @@ define signext i64 @lshr_i64(i64 signext %a, i64 signext %b) {
; MIPS32-LABEL: lshr_i64:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: srlv $1, $5, $7
; MIPS32-NEXT: not $2, $7
; MIPS32-NEXT: xori $2, $7, 31
; MIPS32-NEXT: sll $3, $4, 1
; MIPS32-NEXT: sllv $2, $3, $2
; MIPS32-NEXT: or $3, $2, $1
Expand All @@ -309,7 +309,7 @@ define signext i64 @lshr_i64(i64 signext %a, i64 signext %b) {
; MIPS32R2-LABEL: lshr_i64:
; MIPS32R2: # %bb.0: # %entry
; MIPS32R2-NEXT: srlv $1, $5, $7
; MIPS32R2-NEXT: not $2, $7
; MIPS32R2-NEXT: xori $2, $7, 31
; MIPS32R2-NEXT: sll $3, $4, 1
; MIPS32R2-NEXT: sllv $2, $3, $2
; MIPS32R2-NEXT: or $3, $2, $1
Expand All @@ -322,7 +322,7 @@ define signext i64 @lshr_i64(i64 signext %a, i64 signext %b) {
; MIPS32R6-LABEL: lshr_i64:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: srlv $1, $5, $7
; MIPS32R6-NEXT: not $2, $7
; MIPS32R6-NEXT: xori $2, $7, 31
; MIPS32R6-NEXT: sll $3, $4, 1
; MIPS32R6-NEXT: sllv $2, $3, $2
; MIPS32R6-NEXT: or $1, $2, $1
Expand Down Expand Up @@ -362,9 +362,9 @@ define signext i64 @lshr_i64(i64 signext %a, i64 signext %b) {
; MMR3-LABEL: lshr_i64:
; MMR3: # %bb.0: # %entry
; MMR3-NEXT: srlv $2, $5, $7
; MMR3-NEXT: not16 $3, $7
; MMR3-NEXT: sll16 $5, $4, 1
; MMR3-NEXT: sllv $3, $5, $3
; MMR3-NEXT: xori $1, $7, 31
; MMR3-NEXT: sll16 $3, $4, 1
; MMR3-NEXT: sllv $3, $3, $1
; MMR3-NEXT: or16 $3, $2
; MMR3-NEXT: srlv $2, $4, $7
; MMR3-NEXT: andi16 $4, $7, 32
Expand All @@ -376,7 +376,7 @@ define signext i64 @lshr_i64(i64 signext %a, i64 signext %b) {
; MMR6-LABEL: lshr_i64:
; MMR6: # %bb.0: # %entry
; MMR6-NEXT: srlv $1, $5, $7
; MMR6-NEXT: not16 $2, $7
; MMR6-NEXT: xori $2, $7, 31
; MMR6-NEXT: sll16 $3, $4, 1
; MMR6-NEXT: sllv $2, $3, $2
; MMR6-NEXT: or $1, $2, $1
Expand Down Expand Up @@ -606,7 +606,7 @@ define signext i128 @lshr_i128(i128 signext %a, i128 signext %b) {
; MIPS3-NEXT: # %bb.1: # %entry
; MIPS3-NEXT: dsrlv $1, $5, $7
; MIPS3-NEXT: dsll $2, $4, 1
; MIPS3-NEXT: not $3, $3
; MIPS3-NEXT: xori $3, $3, 63
; MIPS3-NEXT: dsllv $2, $2, $3
; MIPS3-NEXT: or $3, $2, $1
; MIPS3-NEXT: jr $ra
Expand All @@ -620,7 +620,7 @@ define signext i128 @lshr_i128(i128 signext %a, i128 signext %b) {
; MIPS4-NEXT: dsrlv $1, $5, $7
; MIPS4-NEXT: dsll $2, $4, 1
; MIPS4-NEXT: sll $5, $7, 0
; MIPS4-NEXT: not $3, $5
; MIPS4-NEXT: xori $3, $5, 63
; MIPS4-NEXT: dsllv $2, $2, $3
; MIPS4-NEXT: or $3, $2, $1
; MIPS4-NEXT: dsrlv $2, $4, $7
Expand All @@ -634,7 +634,7 @@ define signext i128 @lshr_i128(i128 signext %a, i128 signext %b) {
; MIPS64-NEXT: dsrlv $1, $5, $7
; MIPS64-NEXT: dsll $2, $4, 1
; MIPS64-NEXT: sll $5, $7, 0
; MIPS64-NEXT: not $3, $5
; MIPS64-NEXT: xori $3, $5, 63
; MIPS64-NEXT: dsllv $2, $2, $3
; MIPS64-NEXT: or $3, $2, $1
; MIPS64-NEXT: dsrlv $2, $4, $7
Expand All @@ -648,7 +648,7 @@ define signext i128 @lshr_i128(i128 signext %a, i128 signext %b) {
; MIPS64R2-NEXT: dsrlv $1, $5, $7
; MIPS64R2-NEXT: dsll $2, $4, 1
; MIPS64R2-NEXT: sll $5, $7, 0
; MIPS64R2-NEXT: not $3, $5
; MIPS64R2-NEXT: xori $3, $5, 63
; MIPS64R2-NEXT: dsllv $2, $2, $3
; MIPS64R2-NEXT: or $3, $2, $1
; MIPS64R2-NEXT: dsrlv $2, $4, $7
Expand All @@ -662,7 +662,7 @@ define signext i128 @lshr_i128(i128 signext %a, i128 signext %b) {
; MIPS64R6-NEXT: dsrlv $1, $5, $7
; MIPS64R6-NEXT: dsll $2, $4, 1
; MIPS64R6-NEXT: sll $3, $7, 0
; MIPS64R6-NEXT: not $5, $3
; MIPS64R6-NEXT: xori $5, $3, 63
; MIPS64R6-NEXT: dsllv $2, $2, $5
; MIPS64R6-NEXT: or $1, $2, $1
; MIPS64R6-NEXT: andi $2, $3, 64
Expand Down
26 changes: 13 additions & 13 deletions llvm/test/CodeGen/Mips/llvm-ir/shl.ll
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ define signext i64 @shl_i64(i64 signext %a, i64 signext %b) {
; MIPS2-NEXT: nop
; MIPS2-NEXT: $BB4_3: # %entry
; MIPS2-NEXT: sllv $1, $4, $7
; MIPS2-NEXT: not $2, $7
; MIPS2-NEXT: xori $2, $7, 31
; MIPS2-NEXT: srl $3, $5, 1
; MIPS2-NEXT: srlv $2, $3, $2
; MIPS2-NEXT: or $2, $1, $2
Expand All @@ -356,7 +356,7 @@ define signext i64 @shl_i64(i64 signext %a, i64 signext %b) {
; MIPS32-LABEL: shl_i64:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sllv $1, $4, $7
; MIPS32-NEXT: not $2, $7
; MIPS32-NEXT: xori $2, $7, 31
; MIPS32-NEXT: srl $3, $5, 1
; MIPS32-NEXT: srlv $2, $3, $2
; MIPS32-NEXT: or $2, $1, $2
Expand All @@ -369,7 +369,7 @@ define signext i64 @shl_i64(i64 signext %a, i64 signext %b) {
; MIPS32R2-LABEL: shl_i64:
; MIPS32R2: # %bb.0: # %entry
; MIPS32R2-NEXT: sllv $1, $4, $7
; MIPS32R2-NEXT: not $2, $7
; MIPS32R2-NEXT: xori $2, $7, 31
; MIPS32R2-NEXT: srl $3, $5, 1
; MIPS32R2-NEXT: srlv $2, $3, $2
; MIPS32R2-NEXT: or $2, $1, $2
Expand All @@ -382,7 +382,7 @@ define signext i64 @shl_i64(i64 signext %a, i64 signext %b) {
; MIPS32R6-LABEL: shl_i64:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sllv $1, $4, $7
; MIPS32R6-NEXT: not $2, $7
; MIPS32R6-NEXT: xori $2, $7, 31
; MIPS32R6-NEXT: srl $3, $5, 1
; MIPS32R6-NEXT: srlv $2, $3, $2
; MIPS32R6-NEXT: or $1, $1, $2
Expand Down Expand Up @@ -422,9 +422,9 @@ define signext i64 @shl_i64(i64 signext %a, i64 signext %b) {
; MMR3-LABEL: shl_i64:
; MMR3: # %bb.0: # %entry
; MMR3-NEXT: sllv $3, $4, $7
; MMR3-NEXT: not16 $2, $7
; MMR3-NEXT: srl16 $4, $5, 1
; MMR3-NEXT: srlv $2, $4, $2
; MMR3-NEXT: xori $1, $7, 31
; MMR3-NEXT: srl16 $2, $5, 1
; MMR3-NEXT: srlv $2, $2, $1
; MMR3-NEXT: or16 $2, $3
; MMR3-NEXT: sllv $3, $5, $7
; MMR3-NEXT: andi16 $4, $7, 32
Expand All @@ -436,7 +436,7 @@ define signext i64 @shl_i64(i64 signext %a, i64 signext %b) {
; MMR6-LABEL: shl_i64:
; MMR6: # %bb.0: # %entry
; MMR6-NEXT: sllv $1, $4, $7
; MMR6-NEXT: not16 $2, $7
; MMR6-NEXT: xori $2, $7, 31
; MMR6-NEXT: srl16 $3, $5, 1
; MMR6-NEXT: srlv $2, $3, $2
; MMR6-NEXT: or $1, $1, $2
Expand Down Expand Up @@ -668,7 +668,7 @@ define signext i128 @shl_i128(i128 signext %a, i128 signext %b) {
; MIPS3-NEXT: .LBB5_3: # %entry
; MIPS3-NEXT: dsllv $1, $4, $7
; MIPS3-NEXT: dsrl $2, $5, 1
; MIPS3-NEXT: not $3, $3
; MIPS3-NEXT: xori $3, $3, 63
; MIPS3-NEXT: dsrlv $2, $2, $3
; MIPS3-NEXT: or $2, $1, $2
; MIPS3-NEXT: bnez $8, .LBB5_2
Expand All @@ -682,7 +682,7 @@ define signext i128 @shl_i128(i128 signext %a, i128 signext %b) {
; MIPS4-NEXT: dsllv $1, $4, $7
; MIPS4-NEXT: dsrl $2, $5, 1
; MIPS4-NEXT: sll $4, $7, 0
; MIPS4-NEXT: not $3, $4
; MIPS4-NEXT: xori $3, $4, 63
; MIPS4-NEXT: dsrlv $2, $2, $3
; MIPS4-NEXT: or $2, $1, $2
; MIPS4-NEXT: dsllv $3, $5, $7
Expand All @@ -696,7 +696,7 @@ define signext i128 @shl_i128(i128 signext %a, i128 signext %b) {
; MIPS64-NEXT: dsllv $1, $4, $7
; MIPS64-NEXT: dsrl $2, $5, 1
; MIPS64-NEXT: sll $4, $7, 0
; MIPS64-NEXT: not $3, $4
; MIPS64-NEXT: xori $3, $4, 63
; MIPS64-NEXT: dsrlv $2, $2, $3
; MIPS64-NEXT: or $2, $1, $2
; MIPS64-NEXT: dsllv $3, $5, $7
Expand All @@ -710,7 +710,7 @@ define signext i128 @shl_i128(i128 signext %a, i128 signext %b) {
; MIPS64R2-NEXT: dsllv $1, $4, $7
; MIPS64R2-NEXT: dsrl $2, $5, 1
; MIPS64R2-NEXT: sll $4, $7, 0
; MIPS64R2-NEXT: not $3, $4
; MIPS64R2-NEXT: xori $3, $4, 63
; MIPS64R2-NEXT: dsrlv $2, $2, $3
; MIPS64R2-NEXT: or $2, $1, $2
; MIPS64R2-NEXT: dsllv $3, $5, $7
Expand All @@ -724,7 +724,7 @@ define signext i128 @shl_i128(i128 signext %a, i128 signext %b) {
; MIPS64R6-NEXT: dsllv $1, $4, $7
; MIPS64R6-NEXT: dsrl $2, $5, 1
; MIPS64R6-NEXT: sll $3, $7, 0
; MIPS64R6-NEXT: not $4, $3
; MIPS64R6-NEXT: xori $4, $3, 63
; MIPS64R6-NEXT: dsrlv $2, $2, $4
; MIPS64R6-NEXT: or $1, $1, $2
; MIPS64R6-NEXT: andi $2, $3, 64
Expand Down

0 comments on commit 3dff0e6

Please sign in to comment.