@@ -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