Skip to content

Commit

Permalink
[DAG] visitAND - Fold (and (srl X, C), 1) -> (srl X, BW-1) for signbi…
Browse files Browse the repository at this point in the history
…t extraction (llvm#114992)

If we're masking the LSB of a SRL node result and that is shifting down an extended sign bit, see if we can change the SRL to shift down the MSB directly.

These patterns can occur during legalisation when we've sign extended to a wider type but the SRL is still shifting from the subreg.

Alternative to llvm#114967

Fixes the remaining regression in llvm#112588
  • Loading branch information
RKSimon authored Nov 5, 2024
1 parent d7979c1 commit aef0e77
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 115 deletions.
10 changes: 10 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7392,6 +7392,16 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
return DAG.getNode(ISD::AND, DL, VT, X,
DAG.getNOT(DL, DAG.getNode(Opc, DL, VT, Y, Z), VT));

// Fold (and (srl X, C), 1) -> (srl X, BW-1) for signbit extraction
// If we are shifting down an extended sign bit, see if we can simplify
// this to shifting the MSB directly to expose further simplifications.
// This pattern often appears after sext_inreg legalization.
APInt Amt;
if (sd_match(N, m_And(m_Srl(m_Value(X), m_ConstInt(Amt)), m_One())) &&
Amt.ult(BitWidth - 1) && Amt.uge(BitWidth - DAG.ComputeNumSignBits(X)))
return DAG.getNode(ISD::SRL, DL, VT, X,
DAG.getShiftAmountConstant(BitWidth - 1, VT, DL));

// Masking the negated extension of a boolean is just the zero-extended
// boolean:
// and (sub 0, zext(bool X)), 1 --> zext(bool X)
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/AArch64/srem-seteq-illegal-types.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ define i1 @test_srem_even(i4 %X) nounwind {
; CHECK: // %bb.0:
; CHECK-NEXT: sbfx w8, w0, #0, #4
; CHECK-NEXT: add w8, w8, w8, lsl #1
; CHECK-NEXT: ubfx w9, w8, #7, #1
; CHECK-NEXT: add w8, w9, w8, lsr #4
; CHECK-NEXT: lsr w9, w8, #4
; CHECK-NEXT: add w8, w9, w8, lsr #31
; CHECK-NEXT: mov w9, #6 // =0x6
; CHECK-NEXT: msub w8, w8, w9, w0
; CHECK-NEXT: and w8, w8, #0xf
Expand Down
26 changes: 12 additions & 14 deletions llvm/test/CodeGen/ARM/srem-seteq-illegal-types.ll
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,10 @@ define i1 @test_srem_even(i4 %X) nounwind {
; ARM5-LABEL: test_srem_even:
; ARM5: @ %bb.0:
; ARM5-NEXT: lsl r1, r0, #28
; ARM5-NEXT: mov r2, #1
; ARM5-NEXT: asr r1, r1, #28
; ARM5-NEXT: add r1, r1, r1, lsl #1
; ARM5-NEXT: and r2, r2, r1, lsr #7
; ARM5-NEXT: add r1, r2, r1, lsr #4
; ARM5-NEXT: lsr r2, r1, #4
; ARM5-NEXT: add r1, r2, r1, lsr #31
; ARM5-NEXT: add r1, r1, r1, lsl #1
; ARM5-NEXT: sub r0, r0, r1, lsl #1
; ARM5-NEXT: and r0, r0, #15
Expand All @@ -131,11 +130,10 @@ define i1 @test_srem_even(i4 %X) nounwind {
; ARM6-LABEL: test_srem_even:
; ARM6: @ %bb.0:
; ARM6-NEXT: lsl r1, r0, #28
; ARM6-NEXT: mov r2, #1
; ARM6-NEXT: asr r1, r1, #28
; ARM6-NEXT: add r1, r1, r1, lsl #1
; ARM6-NEXT: and r2, r2, r1, lsr #7
; ARM6-NEXT: add r1, r2, r1, lsr #4
; ARM6-NEXT: lsr r2, r1, #4
; ARM6-NEXT: add r1, r2, r1, lsr #31
; ARM6-NEXT: add r1, r1, r1, lsl #1
; ARM6-NEXT: sub r0, r0, r1, lsl #1
; ARM6-NEXT: and r0, r0, #15
Expand All @@ -148,8 +146,8 @@ define i1 @test_srem_even(i4 %X) nounwind {
; ARM7: @ %bb.0:
; ARM7-NEXT: sbfx r1, r0, #0, #4
; ARM7-NEXT: add r1, r1, r1, lsl #1
; ARM7-NEXT: ubfx r2, r1, #7, #1
; ARM7-NEXT: add r1, r2, r1, lsr #4
; ARM7-NEXT: lsr r2, r1, #4
; ARM7-NEXT: add r1, r2, r1, lsr #31
; ARM7-NEXT: add r1, r1, r1, lsl #1
; ARM7-NEXT: sub r0, r0, r1, lsl #1
; ARM7-NEXT: and r0, r0, #15
Expand All @@ -162,8 +160,8 @@ define i1 @test_srem_even(i4 %X) nounwind {
; ARM8: @ %bb.0:
; ARM8-NEXT: sbfx r1, r0, #0, #4
; ARM8-NEXT: add r1, r1, r1, lsl #1
; ARM8-NEXT: ubfx r2, r1, #7, #1
; ARM8-NEXT: add r1, r2, r1, lsr #4
; ARM8-NEXT: lsr r2, r1, #4
; ARM8-NEXT: add r1, r2, r1, lsr #31
; ARM8-NEXT: add r1, r1, r1, lsl #1
; ARM8-NEXT: sub r0, r0, r1, lsl #1
; ARM8-NEXT: and r0, r0, #15
Expand All @@ -176,8 +174,8 @@ define i1 @test_srem_even(i4 %X) nounwind {
; NEON7: @ %bb.0:
; NEON7-NEXT: sbfx r1, r0, #0, #4
; NEON7-NEXT: add r1, r1, r1, lsl #1
; NEON7-NEXT: ubfx r2, r1, #7, #1
; NEON7-NEXT: add r1, r2, r1, lsr #4
; NEON7-NEXT: lsr r2, r1, #4
; NEON7-NEXT: add r1, r2, r1, lsr #31
; NEON7-NEXT: add r1, r1, r1, lsl #1
; NEON7-NEXT: sub r0, r0, r1, lsl #1
; NEON7-NEXT: and r0, r0, #15
Expand All @@ -190,8 +188,8 @@ define i1 @test_srem_even(i4 %X) nounwind {
; NEON8: @ %bb.0:
; NEON8-NEXT: sbfx r1, r0, #0, #4
; NEON8-NEXT: add r1, r1, r1, lsl #1
; NEON8-NEXT: ubfx r2, r1, #7, #1
; NEON8-NEXT: add r1, r2, r1, lsr #4
; NEON8-NEXT: lsr r2, r1, #4
; NEON8-NEXT: add r1, r2, r1, lsr #31
; NEON8-NEXT: add r1, r1, r1, lsl #1
; NEON8-NEXT: sub r0, r0, r1, lsl #1
; NEON8-NEXT: and r0, r0, #15
Expand Down
22 changes: 10 additions & 12 deletions llvm/test/CodeGen/Mips/srem-seteq-illegal-types.ll
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,16 @@ define i1 @test_srem_even(i4 %X) nounwind {
; MIPSEL-NEXT: sra $1, $1, 28
; MIPSEL-NEXT: sll $2, $1, 1
; MIPSEL-NEXT: addu $1, $2, $1
; MIPSEL-NEXT: srl $2, $1, 4
; MIPSEL-NEXT: srl $1, $1, 7
; MIPSEL-NEXT: andi $1, $1, 1
; MIPSEL-NEXT: addiu $3, $zero, 1
; MIPSEL-NEXT: addu $1, $2, $1
; MIPSEL-NEXT: sll $2, $1, 1
; MIPSEL-NEXT: sll $1, $1, 2
; MIPSEL-NEXT: srl $2, $1, 31
; MIPSEL-NEXT: srl $1, $1, 4
; MIPSEL-NEXT: addu $1, $1, $2
; MIPSEL-NEXT: addiu $2, $zero, 1
; MIPSEL-NEXT: sll $3, $1, 1
; MIPSEL-NEXT: sll $1, $1, 2
; MIPSEL-NEXT: addu $1, $1, $3
; MIPSEL-NEXT: subu $1, $4, $1
; MIPSEL-NEXT: andi $1, $1, 15
; MIPSEL-NEXT: xor $1, $1, $3
; MIPSEL-NEXT: xor $1, $1, $2
; MIPSEL-NEXT: jr $ra
; MIPSEL-NEXT: sltiu $2, $1, 1
;
Expand All @@ -69,10 +68,9 @@ define i1 @test_srem_even(i4 %X) nounwind {
; MIPS64EL-NEXT: sll $3, $2, 1
; MIPS64EL-NEXT: addu $2, $3, $2
; MIPS64EL-NEXT: addiu $3, $zero, 1
; MIPS64EL-NEXT: srl $4, $2, 4
; MIPS64EL-NEXT: srl $2, $2, 7
; MIPS64EL-NEXT: andi $2, $2, 1
; MIPS64EL-NEXT: addu $2, $4, $2
; MIPS64EL-NEXT: srl $4, $2, 31
; MIPS64EL-NEXT: srl $2, $2, 4
; MIPS64EL-NEXT: addu $2, $2, $4
; MIPS64EL-NEXT: sll $4, $2, 1
; MIPS64EL-NEXT: sll $2, $2, 2
; MIPS64EL-NEXT: addu $2, $2, $4
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/PowerPC/srem-seteq-illegal-types.ll
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ define i1 @test_srem_even(i4 %X) nounwind {
; PPC-NEXT: slwi 4, 3, 28
; PPC-NEXT: srawi 4, 4, 28
; PPC-NEXT: mulli 4, 4, 3
; PPC-NEXT: rlwinm 5, 4, 25, 31, 31
; PPC-NEXT: srwi 5, 4, 31
; PPC-NEXT: srwi 4, 4, 4
; PPC-NEXT: add 4, 4, 5
; PPC-NEXT: mulli 4, 4, 6
Expand All @@ -65,7 +65,7 @@ define i1 @test_srem_even(i4 %X) nounwind {
; PPC64LE-NEXT: srawi 4, 4, 28
; PPC64LE-NEXT: slwi 5, 4, 1
; PPC64LE-NEXT: add 4, 4, 5
; PPC64LE-NEXT: rlwinm 5, 4, 25, 31, 31
; PPC64LE-NEXT: srwi 5, 4, 31
; PPC64LE-NEXT: srwi 4, 4, 4
; PPC64LE-NEXT: add 4, 4, 5
; PPC64LE-NEXT: mulli 4, 4, 6
Expand Down
64 changes: 28 additions & 36 deletions llvm/test/CodeGen/RISCV/div-by-constant.ll
Original file line number Diff line number Diff line change
Expand Up @@ -488,21 +488,19 @@ define i8 @sdiv8_constant_no_srai(i8 %a) nounwind {
; RV32IM-NEXT: srai a0, a0, 24
; RV32IM-NEXT: li a1, 86
; RV32IM-NEXT: mul a0, a0, a1
; RV32IM-NEXT: srli a1, a0, 8
; RV32IM-NEXT: slli a0, a0, 16
; RV32IM-NEXT: srli a0, a0, 31
; RV32IM-NEXT: add a0, a1, a0
; RV32IM-NEXT: srli a1, a0, 31
; RV32IM-NEXT: srli a0, a0, 8
; RV32IM-NEXT: add a0, a0, a1
; RV32IM-NEXT: ret
;
; RV32IMZB-LABEL: sdiv8_constant_no_srai:
; RV32IMZB: # %bb.0:
; RV32IMZB-NEXT: sext.b a0, a0
; RV32IMZB-NEXT: li a1, 86
; RV32IMZB-NEXT: mul a0, a0, a1
; RV32IMZB-NEXT: srli a1, a0, 8
; RV32IMZB-NEXT: slli a0, a0, 16
; RV32IMZB-NEXT: srli a0, a0, 31
; RV32IMZB-NEXT: add a0, a1, a0
; RV32IMZB-NEXT: srli a1, a0, 31
; RV32IMZB-NEXT: srli a0, a0, 8
; RV32IMZB-NEXT: add a0, a0, a1
; RV32IMZB-NEXT: ret
;
; RV64IM-LABEL: sdiv8_constant_no_srai:
Expand All @@ -511,21 +509,19 @@ define i8 @sdiv8_constant_no_srai(i8 %a) nounwind {
; RV64IM-NEXT: srai a0, a0, 56
; RV64IM-NEXT: li a1, 86
; RV64IM-NEXT: mul a0, a0, a1
; RV64IM-NEXT: srli a1, a0, 8
; RV64IM-NEXT: slli a0, a0, 48
; RV64IM-NEXT: srli a0, a0, 63
; RV64IM-NEXT: add a0, a1, a0
; RV64IM-NEXT: srli a1, a0, 63
; RV64IM-NEXT: srli a0, a0, 8
; RV64IM-NEXT: add a0, a0, a1
; RV64IM-NEXT: ret
;
; RV64IMZB-LABEL: sdiv8_constant_no_srai:
; RV64IMZB: # %bb.0:
; RV64IMZB-NEXT: sext.b a0, a0
; RV64IMZB-NEXT: li a1, 86
; RV64IMZB-NEXT: mul a0, a0, a1
; RV64IMZB-NEXT: srli a1, a0, 8
; RV64IMZB-NEXT: slli a0, a0, 48
; RV64IMZB-NEXT: srli a0, a0, 63
; RV64IMZB-NEXT: add a0, a1, a0
; RV64IMZB-NEXT: srli a1, a0, 63
; RV64IMZB-NEXT: srli a0, a0, 8
; RV64IMZB-NEXT: add a0, a0, a1
; RV64IMZB-NEXT: ret
%1 = sdiv i8 %a, 3
ret i8 %1
Expand All @@ -538,21 +534,19 @@ define i8 @sdiv8_constant_srai(i8 %a) nounwind {
; RV32IM-NEXT: srai a0, a0, 24
; RV32IM-NEXT: li a1, 103
; RV32IM-NEXT: mul a0, a0, a1
; RV32IM-NEXT: srai a1, a0, 9
; RV32IM-NEXT: slli a0, a0, 16
; RV32IM-NEXT: srli a0, a0, 31
; RV32IM-NEXT: add a0, a1, a0
; RV32IM-NEXT: srli a1, a0, 31
; RV32IM-NEXT: srai a0, a0, 9
; RV32IM-NEXT: add a0, a0, a1
; RV32IM-NEXT: ret
;
; RV32IMZB-LABEL: sdiv8_constant_srai:
; RV32IMZB: # %bb.0:
; RV32IMZB-NEXT: sext.b a0, a0
; RV32IMZB-NEXT: li a1, 103
; RV32IMZB-NEXT: mul a0, a0, a1
; RV32IMZB-NEXT: srai a1, a0, 9
; RV32IMZB-NEXT: slli a0, a0, 16
; RV32IMZB-NEXT: srli a0, a0, 31
; RV32IMZB-NEXT: add a0, a1, a0
; RV32IMZB-NEXT: srli a1, a0, 31
; RV32IMZB-NEXT: srai a0, a0, 9
; RV32IMZB-NEXT: add a0, a0, a1
; RV32IMZB-NEXT: ret
;
; RV64IM-LABEL: sdiv8_constant_srai:
Expand All @@ -561,21 +555,19 @@ define i8 @sdiv8_constant_srai(i8 %a) nounwind {
; RV64IM-NEXT: srai a0, a0, 56
; RV64IM-NEXT: li a1, 103
; RV64IM-NEXT: mul a0, a0, a1
; RV64IM-NEXT: srai a1, a0, 9
; RV64IM-NEXT: slli a0, a0, 48
; RV64IM-NEXT: srli a0, a0, 63
; RV64IM-NEXT: add a0, a1, a0
; RV64IM-NEXT: srli a1, a0, 63
; RV64IM-NEXT: srai a0, a0, 9
; RV64IM-NEXT: add a0, a0, a1
; RV64IM-NEXT: ret
;
; RV64IMZB-LABEL: sdiv8_constant_srai:
; RV64IMZB: # %bb.0:
; RV64IMZB-NEXT: sext.b a0, a0
; RV64IMZB-NEXT: li a1, 103
; RV64IMZB-NEXT: mul a0, a0, a1
; RV64IMZB-NEXT: srai a1, a0, 9
; RV64IMZB-NEXT: slli a0, a0, 48
; RV64IMZB-NEXT: srli a0, a0, 63
; RV64IMZB-NEXT: add a0, a1, a0
; RV64IMZB-NEXT: srli a1, a0, 63
; RV64IMZB-NEXT: srai a0, a0, 9
; RV64IMZB-NEXT: add a0, a0, a1
; RV64IMZB-NEXT: ret
%1 = sdiv i8 %a, 5
ret i8 %1
Expand Down Expand Up @@ -728,7 +720,7 @@ define i16 @sdiv16_constant_no_srai(i16 %a) nounwind {
; RV64IM-NEXT: lui a1, 5
; RV64IM-NEXT: addiw a1, a1, 1366
; RV64IM-NEXT: mul a0, a0, a1
; RV64IM-NEXT: srliw a1, a0, 31
; RV64IM-NEXT: srli a1, a0, 63
; RV64IM-NEXT: srli a0, a0, 16
; RV64IM-NEXT: add a0, a0, a1
; RV64IM-NEXT: ret
Expand All @@ -739,7 +731,7 @@ define i16 @sdiv16_constant_no_srai(i16 %a) nounwind {
; RV64IMZB-NEXT: lui a1, 5
; RV64IMZB-NEXT: addiw a1, a1, 1366
; RV64IMZB-NEXT: mul a0, a0, a1
; RV64IMZB-NEXT: srliw a1, a0, 31
; RV64IMZB-NEXT: srli a1, a0, 63
; RV64IMZB-NEXT: srli a0, a0, 16
; RV64IMZB-NEXT: add a0, a0, a1
; RV64IMZB-NEXT: ret
Expand Down Expand Up @@ -778,7 +770,7 @@ define i16 @sdiv16_constant_srai(i16 %a) nounwind {
; RV64IM-NEXT: lui a1, 6
; RV64IM-NEXT: addiw a1, a1, 1639
; RV64IM-NEXT: mul a0, a0, a1
; RV64IM-NEXT: srliw a1, a0, 31
; RV64IM-NEXT: srli a1, a0, 63
; RV64IM-NEXT: srai a0, a0, 17
; RV64IM-NEXT: add a0, a0, a1
; RV64IM-NEXT: ret
Expand All @@ -789,7 +781,7 @@ define i16 @sdiv16_constant_srai(i16 %a) nounwind {
; RV64IMZB-NEXT: lui a1, 6
; RV64IMZB-NEXT: addiw a1, a1, 1639
; RV64IMZB-NEXT: mul a0, a0, a1
; RV64IMZB-NEXT: srliw a1, a0, 31
; RV64IMZB-NEXT: srli a1, a0, 63
; RV64IMZB-NEXT: srai a0, a0, 17
; RV64IMZB-NEXT: add a0, a0, a1
; RV64IMZB-NEXT: ret
Expand Down
16 changes: 7 additions & 9 deletions llvm/test/CodeGen/RISCV/div.ll
Original file line number Diff line number Diff line change
Expand Up @@ -980,10 +980,9 @@ define i8 @sdiv8_constant(i8 %a) nounwind {
; RV32IM-NEXT: srai a0, a0, 24
; RV32IM-NEXT: li a1, 103
; RV32IM-NEXT: mul a0, a0, a1
; RV32IM-NEXT: srai a1, a0, 9
; RV32IM-NEXT: slli a0, a0, 16
; RV32IM-NEXT: srli a0, a0, 31
; RV32IM-NEXT: add a0, a1, a0
; RV32IM-NEXT: srli a1, a0, 31
; RV32IM-NEXT: srai a0, a0, 9
; RV32IM-NEXT: add a0, a0, a1
; RV32IM-NEXT: ret
;
; RV64I-LABEL: sdiv8_constant:
Expand All @@ -1004,10 +1003,9 @@ define i8 @sdiv8_constant(i8 %a) nounwind {
; RV64IM-NEXT: srai a0, a0, 56
; RV64IM-NEXT: li a1, 103
; RV64IM-NEXT: mul a0, a0, a1
; RV64IM-NEXT: srai a1, a0, 9
; RV64IM-NEXT: slli a0, a0, 48
; RV64IM-NEXT: srli a0, a0, 63
; RV64IM-NEXT: add a0, a1, a0
; RV64IM-NEXT: srli a1, a0, 63
; RV64IM-NEXT: srai a0, a0, 9
; RV64IM-NEXT: add a0, a0, a1
; RV64IM-NEXT: ret
%1 = sdiv i8 %a, 5
ret i8 %1
Expand Down Expand Up @@ -1193,7 +1191,7 @@ define i16 @sdiv16_constant(i16 %a) nounwind {
; RV64IM-NEXT: lui a1, 6
; RV64IM-NEXT: addiw a1, a1, 1639
; RV64IM-NEXT: mul a0, a0, a1
; RV64IM-NEXT: srliw a1, a0, 31
; RV64IM-NEXT: srli a1, a0, 63
; RV64IM-NEXT: srai a0, a0, 17
; RV64IM-NEXT: add a0, a0, a1
; RV64IM-NEXT: ret
Expand Down
Loading

0 comments on commit aef0e77

Please sign in to comment.