@@ -511,3 +511,212 @@ exit:
511511 %resigned = call i64 @llvm.ptrauth.resign (i64 %addr , i32 2 , i64 %auth.disc , i32 3 , i64 %sign.disc )
512512 ret i64 %resigned
513513}
514+
515+ ; Test other pseudo instructions accepting discriminator components as separate
516+ ; operands: AUTH_TCRETURN, AUTH_TCRETURN_BTI and BLRA.
517+ ; FIXME: Test BLRA_RVMARKER.
518+ ;
519+ ; A few other PAuth-related pseudo instructions exist that accept address and
520+ ; integer discriminator components, but the way they are currently selected both
521+ ; by DAGISel and GlobalISel is not susceptible to this issue:
522+ ; * MOVaddrPAC and LOADgotPAC are only emitted when lowering `ptrauth` constants
523+ ; in LLVM IR, so their discriminators are never expressed via blend.
524+ ; * BRA is only emitted for indirect branch, and its address discriminator is
525+ ; always XZR.
526+ ;
527+ ; Furthermore, a few more pseudo instructions have HasPAuth in their predicates,
528+ ; but only have constant discriminator or no discriminator operands at all:
529+ ; LOADgotAUTH and LOADauthptrstatic.
530+ ;
531+ ; The below test cases specify non-default preserve_nonecc calling convention -
532+ ; this is to prevent meaningless divergence between Darwin and ELF targets due
533+ ; to difference in callee-saved register masks specified in call instructions.
534+
535+ define preserve_nonecc i64 @auth_tcreturn_blend_components (ptr %callee , i1 %cond.b ) {
536+ ; DAGISEL-LABEL: name: auth_tcreturn_blend_components
537+ ; DAGISEL: bb.0.entry:
538+ ; DAGISEL-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
539+ ; DAGISEL-NEXT: liveins: $x20, $w0
540+ ; DAGISEL-NEXT: {{ $}}
541+ ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
542+ ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:tcgprnotx16x17 = COPY $x20
543+ ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
544+ ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
545+ ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48
546+ ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:tcgpr64 = COPY [[MOVKXi]]
547+ ; DAGISEL-NEXT: TBZW [[COPY]], 0, %bb.2
548+ ; DAGISEL-NEXT: B %bb.1
549+ ; DAGISEL-NEXT: {{ $}}
550+ ; DAGISEL-NEXT: bb.1.next:
551+ ; DAGISEL-NEXT: successors: %bb.2(0x80000000)
552+ ; DAGISEL-NEXT: {{ $}}
553+ ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]]
554+ ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]]
555+ ; DAGISEL-NEXT: {{ $}}
556+ ; DAGISEL-NEXT: bb.2.exit:
557+ ; DAGISEL-NEXT: AUTH_TCRETURN [[COPY1]], 0, 1, 0, [[COPY2]], csr_aarch64_noneregs, implicit-def dead $x16, implicit-def dead $x17, implicit $sp
558+ ;
559+ ; GISEL-LABEL: name: auth_tcreturn_blend_components
560+ ; GISEL: bb.1.entry:
561+ ; GISEL-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
562+ ; GISEL-NEXT: liveins: $w0, $x20
563+ ; GISEL-NEXT: {{ $}}
564+ ; GISEL-NEXT: [[COPY:%[0-9]+]]:tcgprnotx16x17 = COPY $x20
565+ ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
566+ ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
567+ ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:tcgpr64 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
568+ ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64common = MOVKXi [[LDRXui]], 42, 48
569+ ; GISEL-NEXT: TBZW [[COPY1]], 0, %bb.3
570+ ; GISEL-NEXT: B %bb.2
571+ ; GISEL-NEXT: {{ $}}
572+ ; GISEL-NEXT: bb.2.next:
573+ ; GISEL-NEXT: successors: %bb.3(0x80000000)
574+ ; GISEL-NEXT: {{ $}}
575+ ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[MOVKXi]]
576+ ; GISEL-NEXT: {{ $}}
577+ ; GISEL-NEXT: bb.3.exit:
578+ ; GISEL-NEXT: AUTH_TCRETURN [[COPY]], 0, 1, 42, [[LDRXui]], csr_aarch64_noneregs, implicit-def $x16, implicit-def $x17, implicit $sp
579+ entry:
580+ %addrdisc = load i64 , ptr @discvar
581+ %disc = call i64 @llvm.ptrauth.blend (i64 %addrdisc , i64 42 )
582+ br i1 %cond.b , label %next , label %exit
583+
584+ next:
585+ call void asm sideeffect "nop" , "r" (i64 %disc )
586+ br label %exit
587+
588+ exit:
589+ %result = tail call preserve_nonecc i64 %callee () [ "ptrauth" (i32 1 , i64 %disc ) ]
590+ ret i64 %result
591+ }
592+
593+ define preserve_nonecc i64 @auth_tcreturn_bti_blend_components (ptr %callee , i1 %cond.b ) "branch-target-enforcement" ="true" {
594+ ; DAGISEL-LABEL: name: auth_tcreturn_bti_blend_components
595+ ; DAGISEL: bb.0.entry:
596+ ; DAGISEL-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
597+ ; DAGISEL-NEXT: liveins: $x20, $w0
598+ ; DAGISEL-NEXT: {{ $}}
599+ ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
600+ ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x20
601+ ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
602+ ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
603+ ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48
604+ ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:tcgprnotx16x17 = COPY [[MOVKXi]]
605+ ; DAGISEL-NEXT: TBZW [[COPY]], 0, %bb.2
606+ ; DAGISEL-NEXT: B %bb.1
607+ ; DAGISEL-NEXT: {{ $}}
608+ ; DAGISEL-NEXT: bb.1.next:
609+ ; DAGISEL-NEXT: successors: %bb.2(0x80000000)
610+ ; DAGISEL-NEXT: {{ $}}
611+ ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]]
612+ ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]]
613+ ; DAGISEL-NEXT: {{ $}}
614+ ; DAGISEL-NEXT: bb.2.exit:
615+ ; DAGISEL-NEXT: [[COPY4:%[0-9]+]]:tcgprx16x17 = COPY [[COPY1]]
616+ ; DAGISEL-NEXT: AUTH_TCRETURN_BTI [[COPY4]], 0, 1, 0, [[COPY2]], csr_aarch64_noneregs, implicit-def dead $x16, implicit-def dead $x17, implicit $sp
617+ ;
618+ ; GISEL-LABEL: name: auth_tcreturn_bti_blend_components
619+ ; GISEL: bb.1.entry:
620+ ; GISEL-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
621+ ; GISEL-NEXT: liveins: $w0, $x20
622+ ; GISEL-NEXT: {{ $}}
623+ ; GISEL-NEXT: [[COPY:%[0-9]+]]:tcgprx16x17 = COPY $x20
624+ ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
625+ ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
626+ ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:tcgprnotx16x17 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
627+ ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64common = MOVKXi [[LDRXui]], 42, 48
628+ ; GISEL-NEXT: TBZW [[COPY1]], 0, %bb.3
629+ ; GISEL-NEXT: B %bb.2
630+ ; GISEL-NEXT: {{ $}}
631+ ; GISEL-NEXT: bb.2.next:
632+ ; GISEL-NEXT: successors: %bb.3(0x80000000)
633+ ; GISEL-NEXT: {{ $}}
634+ ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[MOVKXi]]
635+ ; GISEL-NEXT: {{ $}}
636+ ; GISEL-NEXT: bb.3.exit:
637+ ; GISEL-NEXT: AUTH_TCRETURN_BTI [[COPY]], 0, 1, 42, [[LDRXui]], csr_aarch64_noneregs, implicit-def $x16, implicit-def $x17, implicit $sp
638+ entry:
639+ %addrdisc = load i64 , ptr @discvar
640+ %disc = call i64 @llvm.ptrauth.blend (i64 %addrdisc , i64 42 )
641+ br i1 %cond.b , label %next , label %exit
642+
643+ next:
644+ call void asm sideeffect "nop" , "r" (i64 %disc )
645+ br label %exit
646+
647+ exit:
648+ %result = tail call preserve_nonecc i64 %callee () [ "ptrauth" (i32 1 , i64 %disc ) ]
649+ ret i64 %result
650+ }
651+
652+ define preserve_nonecc i64 @blra_blend_components (ptr %callee , i1 %cond.b ) {
653+ ; DAGISEL-LABEL: name: blra_blend_components
654+ ; DAGISEL: bb.0.entry:
655+ ; DAGISEL-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
656+ ; DAGISEL-NEXT: liveins: $x20, $w0
657+ ; DAGISEL-NEXT: {{ $}}
658+ ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
659+ ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY $x20
660+ ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
661+ ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
662+ ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48
663+ ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[MOVKXi]]
664+ ; DAGISEL-NEXT: TBZW [[COPY]], 0, %bb.2
665+ ; DAGISEL-NEXT: B %bb.1
666+ ; DAGISEL-NEXT: {{ $}}
667+ ; DAGISEL-NEXT: bb.1.next:
668+ ; DAGISEL-NEXT: successors: %bb.2(0x80000000)
669+ ; DAGISEL-NEXT: {{ $}}
670+ ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]]
671+ ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]]
672+ ; DAGISEL-NEXT: {{ $}}
673+ ; DAGISEL-NEXT: bb.2.exit:
674+ ; DAGISEL-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
675+ ; DAGISEL-NEXT: BLRA [[COPY1]], 1, 0, [[COPY2]], csr_aarch64_noneregs, implicit-def dead $x16, implicit-def dead $x17, implicit-def dead $lr, implicit $sp, implicit-def $sp, implicit-def $x0
676+ ; DAGISEL-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
677+ ; DAGISEL-NEXT: [[COPY4:%[0-9]+]]:gpr64sp = COPY $x0
678+ ; DAGISEL-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY4]], 123, 0
679+ ; DAGISEL-NEXT: $x0 = COPY [[ADDXri]]
680+ ; DAGISEL-NEXT: RET_ReallyLR implicit $x0
681+ ;
682+ ; GISEL-LABEL: name: blra_blend_components
683+ ; GISEL: bb.1.entry:
684+ ; GISEL-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
685+ ; GISEL-NEXT: liveins: $w0, $x20
686+ ; GISEL-NEXT: {{ $}}
687+ ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64noip = COPY $x20
688+ ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
689+ ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
690+ ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
691+ ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64common = MOVKXi [[LDRXui]], 42, 48
692+ ; GISEL-NEXT: TBZW [[COPY1]], 0, %bb.3
693+ ; GISEL-NEXT: B %bb.2
694+ ; GISEL-NEXT: {{ $}}
695+ ; GISEL-NEXT: bb.2.next:
696+ ; GISEL-NEXT: successors: %bb.3(0x80000000)
697+ ; GISEL-NEXT: {{ $}}
698+ ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[MOVKXi]]
699+ ; GISEL-NEXT: {{ $}}
700+ ; GISEL-NEXT: bb.3.exit:
701+ ; GISEL-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
702+ ; GISEL-NEXT: BLRA [[COPY]], 1, 42, [[LDRXui]], csr_aarch64_noneregs, implicit-def $x16, implicit-def $x17, implicit-def $lr, implicit $sp, implicit-def $x0
703+ ; GISEL-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
704+ ; GISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64sp = COPY $x0
705+ ; GISEL-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY2]], 123, 0
706+ ; GISEL-NEXT: $x0 = COPY [[ADDXri]]
707+ ; GISEL-NEXT: RET_ReallyLR implicit $x0
708+ entry:
709+ %addrdisc = load i64 , ptr @discvar
710+ %disc = call i64 @llvm.ptrauth.blend (i64 %addrdisc , i64 42 )
711+ br i1 %cond.b , label %next , label %exit
712+
713+ next:
714+ call void asm sideeffect "nop" , "r" (i64 %disc )
715+ br label %exit
716+
717+ exit:
718+ %tmp = call preserve_nonecc i64 %callee () [ "ptrauth" (i32 1 , i64 %disc ) ]
719+ ; Prevent tail call.
720+ %result = add i64 %tmp , 123
721+ ret i64 %result
722+ }
0 commit comments