@@ -575,3 +575,212 @@ exit:
575575 %resigned = call i64 @llvm.ptrauth.resign (i64 %addr , i32 2 , i64 %auth.disc , i32 3 , i64 %sign.disc )
576576 ret i64 %resigned
577577}
578+
579+ ; Test other pseudo instructions accepting discriminator components as separate
580+ ; operands: AUTH_TCRETURN, AUTH_TCRETURN_BTI and BLRA.
581+ ; FIXME: Test BLRA_RVMARKER.
582+ ;
583+ ; A few other PAuth-related pseudo instructions exist that accept address and
584+ ; integer discriminator components, but the way they are currently selected both
585+ ; by DAGISel and GlobalISel is not susceptible to this issue:
586+ ; * MOVaddrPAC and LOADgotPAC are only emitted when lowering `ptrauth` constants
587+ ; in LLVM IR, so their discriminators are never expressed via blend.
588+ ; * BRA is only emitted for indirect branch, and its address discriminator is
589+ ; always XZR.
590+ ;
591+ ; Furthermore, a few more pseudo instructions have HasPAuth in their predicates,
592+ ; but only have constant discriminator or no discriminator operands at all:
593+ ; LOADgotAUTH and LOADauthptrstatic.
594+ ;
595+ ; The below test cases specify non-default preserve_nonecc calling convention -
596+ ; this is to prevent meaningless divergence between Darwin and ELF targets due
597+ ; to difference in callee-saved register masks specified in call instructions.
598+
599+ define preserve_nonecc i64 @auth_tcreturn_blend_components (ptr %callee , i1 %cond.b ) {
600+ ; DAGISEL-LABEL: name: auth_tcreturn_blend_components
601+ ; DAGISEL: bb.0.entry:
602+ ; DAGISEL-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
603+ ; DAGISEL-NEXT: liveins: $x20, $w0
604+ ; DAGISEL-NEXT: {{ $}}
605+ ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
606+ ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:tcgprnotx16x17 = COPY $x20
607+ ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
608+ ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
609+ ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48
610+ ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:tcgpr64 = COPY [[MOVKXi]]
611+ ; DAGISEL-NEXT: TBZW [[COPY]], 0, %bb.2
612+ ; DAGISEL-NEXT: B %bb.1
613+ ; DAGISEL-NEXT: {{ $}}
614+ ; DAGISEL-NEXT: bb.1.next:
615+ ; DAGISEL-NEXT: successors: %bb.2(0x80000000)
616+ ; DAGISEL-NEXT: {{ $}}
617+ ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]]
618+ ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]]
619+ ; DAGISEL-NEXT: {{ $}}
620+ ; DAGISEL-NEXT: bb.2.exit:
621+ ; DAGISEL-NEXT: AUTH_TCRETURN [[COPY1]], 0, 1, 0, [[COPY2]], csr_aarch64_noneregs, implicit-def dead $x16, implicit-def dead $x17, implicit $sp
622+ ;
623+ ; GISEL-LABEL: name: auth_tcreturn_blend_components
624+ ; GISEL: bb.1.entry:
625+ ; GISEL-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
626+ ; GISEL-NEXT: liveins: $w0, $x20
627+ ; GISEL-NEXT: {{ $}}
628+ ; GISEL-NEXT: [[COPY:%[0-9]+]]:tcgprnotx16x17 = COPY $x20
629+ ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
630+ ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
631+ ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:tcgpr64 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
632+ ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64common = MOVKXi [[LDRXui]], 42, 48
633+ ; GISEL-NEXT: TBZW [[COPY1]], 0, %bb.3
634+ ; GISEL-NEXT: B %bb.2
635+ ; GISEL-NEXT: {{ $}}
636+ ; GISEL-NEXT: bb.2.next:
637+ ; GISEL-NEXT: successors: %bb.3(0x80000000)
638+ ; GISEL-NEXT: {{ $}}
639+ ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[MOVKXi]]
640+ ; GISEL-NEXT: {{ $}}
641+ ; GISEL-NEXT: bb.3.exit:
642+ ; GISEL-NEXT: AUTH_TCRETURN [[COPY]], 0, 1, 42, [[LDRXui]], csr_aarch64_noneregs, implicit-def $x16, implicit-def $x17, implicit $sp
643+ entry:
644+ %addrdisc = load i64 , ptr @discvar
645+ %disc = call i64 @llvm.ptrauth.blend (i64 %addrdisc , i64 42 )
646+ br i1 %cond.b , label %next , label %exit
647+
648+ next:
649+ call void asm sideeffect "nop" , "r" (i64 %disc )
650+ br label %exit
651+
652+ exit:
653+ %result = tail call preserve_nonecc i64 %callee () [ "ptrauth" (i32 1 , i64 %disc ) ]
654+ ret i64 %result
655+ }
656+
657+ define preserve_nonecc i64 @auth_tcreturn_bti_blend_components (ptr %callee , i1 %cond.b ) "branch-target-enforcement" ="true" {
658+ ; DAGISEL-LABEL: name: auth_tcreturn_bti_blend_components
659+ ; DAGISEL: bb.0.entry:
660+ ; DAGISEL-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
661+ ; DAGISEL-NEXT: liveins: $x20, $w0
662+ ; DAGISEL-NEXT: {{ $}}
663+ ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
664+ ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x20
665+ ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
666+ ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
667+ ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48
668+ ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:tcgprnotx16x17 = COPY [[MOVKXi]]
669+ ; DAGISEL-NEXT: TBZW [[COPY]], 0, %bb.2
670+ ; DAGISEL-NEXT: B %bb.1
671+ ; DAGISEL-NEXT: {{ $}}
672+ ; DAGISEL-NEXT: bb.1.next:
673+ ; DAGISEL-NEXT: successors: %bb.2(0x80000000)
674+ ; DAGISEL-NEXT: {{ $}}
675+ ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]]
676+ ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]]
677+ ; DAGISEL-NEXT: {{ $}}
678+ ; DAGISEL-NEXT: bb.2.exit:
679+ ; DAGISEL-NEXT: [[COPY4:%[0-9]+]]:tcgprx16x17 = COPY [[COPY1]]
680+ ; DAGISEL-NEXT: AUTH_TCRETURN_BTI [[COPY4]], 0, 1, 0, [[COPY2]], csr_aarch64_noneregs, implicit-def dead $x16, implicit-def dead $x17, implicit $sp
681+ ;
682+ ; GISEL-LABEL: name: auth_tcreturn_bti_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]+]]:tcgprx16x17 = 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]+]]:tcgprnotx16x17 = 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: AUTH_TCRETURN_BTI [[COPY]], 0, 1, 42, [[LDRXui]], csr_aarch64_noneregs, implicit-def $x16, implicit-def $x17, implicit $sp
702+ entry:
703+ %addrdisc = load i64 , ptr @discvar
704+ %disc = call i64 @llvm.ptrauth.blend (i64 %addrdisc , i64 42 )
705+ br i1 %cond.b , label %next , label %exit
706+
707+ next:
708+ call void asm sideeffect "nop" , "r" (i64 %disc )
709+ br label %exit
710+
711+ exit:
712+ %result = tail call preserve_nonecc i64 %callee () [ "ptrauth" (i32 1 , i64 %disc ) ]
713+ ret i64 %result
714+ }
715+
716+ define preserve_nonecc i64 @blra_blend_components (ptr %callee , i1 %cond.b ) {
717+ ; DAGISEL-LABEL: name: blra_blend_components
718+ ; DAGISEL: bb.0.entry:
719+ ; DAGISEL-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
720+ ; DAGISEL-NEXT: liveins: $x20, $w0
721+ ; DAGISEL-NEXT: {{ $}}
722+ ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
723+ ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY $x20
724+ ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
725+ ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
726+ ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48
727+ ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[MOVKXi]]
728+ ; DAGISEL-NEXT: TBZW [[COPY]], 0, %bb.2
729+ ; DAGISEL-NEXT: B %bb.1
730+ ; DAGISEL-NEXT: {{ $}}
731+ ; DAGISEL-NEXT: bb.1.next:
732+ ; DAGISEL-NEXT: successors: %bb.2(0x80000000)
733+ ; DAGISEL-NEXT: {{ $}}
734+ ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]]
735+ ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]]
736+ ; DAGISEL-NEXT: {{ $}}
737+ ; DAGISEL-NEXT: bb.2.exit:
738+ ; DAGISEL-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
739+ ; 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
740+ ; DAGISEL-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
741+ ; DAGISEL-NEXT: [[COPY4:%[0-9]+]]:gpr64sp = COPY $x0
742+ ; DAGISEL-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY4]], 123, 0
743+ ; DAGISEL-NEXT: $x0 = COPY [[ADDXri]]
744+ ; DAGISEL-NEXT: RET_ReallyLR implicit $x0
745+ ;
746+ ; GISEL-LABEL: name: blra_blend_components
747+ ; GISEL: bb.1.entry:
748+ ; GISEL-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
749+ ; GISEL-NEXT: liveins: $w0, $x20
750+ ; GISEL-NEXT: {{ $}}
751+ ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64noip = COPY $x20
752+ ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
753+ ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
754+ ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
755+ ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64common = MOVKXi [[LDRXui]], 42, 48
756+ ; GISEL-NEXT: TBZW [[COPY1]], 0, %bb.3
757+ ; GISEL-NEXT: B %bb.2
758+ ; GISEL-NEXT: {{ $}}
759+ ; GISEL-NEXT: bb.2.next:
760+ ; GISEL-NEXT: successors: %bb.3(0x80000000)
761+ ; GISEL-NEXT: {{ $}}
762+ ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[MOVKXi]]
763+ ; GISEL-NEXT: {{ $}}
764+ ; GISEL-NEXT: bb.3.exit:
765+ ; GISEL-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
766+ ; GISEL-NEXT: BLRA [[COPY]], 1, 42, [[LDRXui]], csr_aarch64_noneregs, implicit-def $x16, implicit-def $x17, implicit-def $lr, implicit $sp, implicit-def $x0
767+ ; GISEL-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
768+ ; GISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64sp = COPY $x0
769+ ; GISEL-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY2]], 123, 0
770+ ; GISEL-NEXT: $x0 = COPY [[ADDXri]]
771+ ; GISEL-NEXT: RET_ReallyLR implicit $x0
772+ entry:
773+ %addrdisc = load i64 , ptr @discvar
774+ %disc = call i64 @llvm.ptrauth.blend (i64 %addrdisc , i64 42 )
775+ br i1 %cond.b , label %next , label %exit
776+
777+ next:
778+ call void asm sideeffect "nop" , "r" (i64 %disc )
779+ br label %exit
780+
781+ exit:
782+ %tmp = call preserve_nonecc i64 %callee () [ "ptrauth" (i32 1 , i64 %disc ) ]
783+ ; Prevent tail call.
784+ %result = add i64 %tmp , 123
785+ ret i64 %result
786+ }
0 commit comments