Skip to content

Commit 6414ae6

Browse files
authored
[RISCV] Do not commute with shift if we might break a qc.shladd pattern (#155367)
Similar to what we do if might break a `sh{1,2,3}add` pattern.
1 parent 51230d9 commit 6414ae6

File tree

2 files changed

+117
-3
lines changed

2 files changed

+117
-3
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21127,9 +21127,14 @@ bool RISCVTargetLowering::isDesirableToCommuteWithShift(
2112721127
auto *C1 = dyn_cast<ConstantSDNode>(N0->getOperand(1));
2112821128
auto *C2 = dyn_cast<ConstantSDNode>(N->getOperand(1));
2112921129

21130-
// Bail if we might break a sh{1,2,3}add pattern.
21131-
if ((Subtarget.hasStdExtZba() || Subtarget.hasVendorXAndesPerf()) && C2 &&
21132-
C2->getZExtValue() >= 1 && C2->getZExtValue() <= 3 && N->hasOneUse() &&
21130+
bool IsShXAdd =
21131+
(Subtarget.hasStdExtZba() || Subtarget.hasVendorXAndesPerf()) && C2 &&
21132+
C2->getZExtValue() >= 1 && C2->getZExtValue() <= 3;
21133+
bool IsQCShlAdd = Subtarget.hasVendorXqciac() && C2 &&
21134+
C2->getZExtValue() >= 4 && C2->getZExtValue() <= 31;
21135+
21136+
// Bail if we might break a sh{1,2,3}add/qc.shladd pattern.
21137+
if ((IsShXAdd || IsQCShlAdd) && N->hasOneUse() &&
2113321138
N->user_begin()->getOpcode() == ISD::ADD &&
2113421139
!isUsedByLdSt(*N->user_begin(), nullptr) &&
2113521140
!isa<ConstantSDNode>(N->user_begin()->getOperand(1)))

llvm/test/CodeGen/RISCV/xqciac.ll

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,112 @@ define i32 @testmuliaddnegimm(i32 %a) {
490490
%add = add i32 %mul, 3
491491
ret i32 %add
492492
}
493+
494+
define i32 @add_shl_OneUse_1(i32 %x) {
495+
; RV32IM-LABEL: add_shl_OneUse_1:
496+
; RV32IM: # %bb.0:
497+
; RV32IM-NEXT: ori a1, a0, 1
498+
; RV32IM-NEXT: slli a0, a0, 4
499+
; RV32IM-NEXT: ori a0, a0, 16
500+
; RV32IM-NEXT: add a0, a0, a1
501+
; RV32IM-NEXT: ret
502+
;
503+
; RV32IMXQCIAC-LABEL: add_shl_OneUse_1:
504+
; RV32IMXQCIAC: # %bb.0:
505+
; RV32IMXQCIAC-NEXT: ori a0, a0, 1
506+
; RV32IMXQCIAC-NEXT: qc.shladd a0, a0, a0, 4
507+
; RV32IMXQCIAC-NEXT: ret
508+
;
509+
; RV32IZBAMXQCIAC-LABEL: add_shl_OneUse_1:
510+
; RV32IZBAMXQCIAC: # %bb.0:
511+
; RV32IZBAMXQCIAC-NEXT: ori a0, a0, 1
512+
; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a0, a0, 4
513+
; RV32IZBAMXQCIAC-NEXT: ret
514+
%or = or i32 %x, 1
515+
%mul = shl i32 %or, 4
516+
%add = add i32 %mul, %or
517+
ret i32 %add
518+
}
519+
520+
define i32 @add_shl_OneUse_2(i32 %x) {
521+
; RV32IM-LABEL: add_shl_OneUse_2:
522+
; RV32IM: # %bb.0:
523+
; RV32IM-NEXT: ori a1, a0, 1
524+
; RV32IM-NEXT: slli a0, a0, 10
525+
; RV32IM-NEXT: ori a0, a0, 1024
526+
; RV32IM-NEXT: add a0, a0, a1
527+
; RV32IM-NEXT: ret
528+
;
529+
; RV32IMXQCIAC-LABEL: add_shl_OneUse_2:
530+
; RV32IMXQCIAC: # %bb.0:
531+
; RV32IMXQCIAC-NEXT: ori a0, a0, 1
532+
; RV32IMXQCIAC-NEXT: qc.shladd a0, a0, a0, 10
533+
; RV32IMXQCIAC-NEXT: ret
534+
;
535+
; RV32IZBAMXQCIAC-LABEL: add_shl_OneUse_2:
536+
; RV32IZBAMXQCIAC: # %bb.0:
537+
; RV32IZBAMXQCIAC-NEXT: ori a0, a0, 1
538+
; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a0, a0, 10
539+
; RV32IZBAMXQCIAC-NEXT: ret
540+
%or = or i32 %x, 1
541+
%mul = shl i32 %or, 10
542+
%add = add i32 %mul, %or
543+
ret i32 %add
544+
}
545+
546+
; For shifts greater than 10 the ori immediate cannot fit within 12 bits so
547+
; we don't commute with shift and generate qc.shaldd
548+
define i32 @add_shl_OneUse_3(i32 %x) {
549+
; RV32IM-LABEL: add_shl_OneUse_3:
550+
; RV32IM: # %bb.0:
551+
; RV32IM-NEXT: ori a0, a0, 1
552+
; RV32IM-NEXT: slli a1, a0, 11
553+
; RV32IM-NEXT: add a0, a1, a0
554+
; RV32IM-NEXT: ret
555+
;
556+
; RV32IMXQCIAC-LABEL: add_shl_OneUse_3:
557+
; RV32IMXQCIAC: # %bb.0:
558+
; RV32IMXQCIAC-NEXT: ori a0, a0, 1
559+
; RV32IMXQCIAC-NEXT: qc.shladd a0, a0, a0, 11
560+
; RV32IMXQCIAC-NEXT: ret
561+
;
562+
; RV32IZBAMXQCIAC-LABEL: add_shl_OneUse_3:
563+
; RV32IZBAMXQCIAC: # %bb.0:
564+
; RV32IZBAMXQCIAC-NEXT: ori a0, a0, 1
565+
; RV32IZBAMXQCIAC-NEXT: qc.shladd a0, a0, a0, 11
566+
; RV32IZBAMXQCIAC-NEXT: ret
567+
%or = or i32 %x, 1
568+
%mul = shl i32 %or, 11
569+
%add = add i32 %mul, %or
570+
ret i32 %add
571+
}
572+
573+
; The shift left gets converted early and as a result we cannot
574+
; generate the qc.shladd.
575+
; FIXME: Should we handle this case and generate qc.shladd if possible?
576+
define i32 @add_shl_moreOneUse_4(i32 %x) {
577+
; RV32IM-LABEL: add_shl_moreOneUse_4:
578+
; RV32IM: # %bb.0:
579+
; RV32IM-NEXT: ori a0, a0, 7
580+
; RV32IM-NEXT: lui a1, 524288
581+
; RV32IM-NEXT: add a0, a0, a1
582+
; RV32IM-NEXT: ret
583+
;
584+
; RV32IMXQCIAC-LABEL: add_shl_moreOneUse_4:
585+
; RV32IMXQCIAC: # %bb.0:
586+
; RV32IMXQCIAC-NEXT: ori a0, a0, 7
587+
; RV32IMXQCIAC-NEXT: lui a1, 524288
588+
; RV32IMXQCIAC-NEXT: add a0, a0, a1
589+
; RV32IMXQCIAC-NEXT: ret
590+
;
591+
; RV32IZBAMXQCIAC-LABEL: add_shl_moreOneUse_4:
592+
; RV32IZBAMXQCIAC: # %bb.0:
593+
; RV32IZBAMXQCIAC-NEXT: ori a0, a0, 7
594+
; RV32IZBAMXQCIAC-NEXT: lui a1, 524288
595+
; RV32IZBAMXQCIAC-NEXT: add a0, a0, a1
596+
; RV32IZBAMXQCIAC-NEXT: ret
597+
%or = or i32 %x, 7
598+
%mul = shl i32 %or, 31
599+
%add = add i32 %mul, %or
600+
ret i32 %add
601+
}

0 commit comments

Comments
 (0)