@@ -434,3 +434,212 @@ exit:
434434 %resigned = call i64 @llvm.ptrauth.resign (i64 %addr , i32 2 , i64 %auth.disc , i32 3 , i64 %sign.disc )
435435 ret i64 %resigned
436436}
437+
438+ ; Test other pseudo instructions accepting discriminator components as separate
439+ ; operands: AUTH_TCRETURN, AUTH_TCRETURN_BTI and BLRA.
440+ ; FIXME: Test BLRA_RVMARKER.
441+ ;
442+ ; A few other PAuth-related pseudo instructions exist that accept address and
443+ ; integer discriminator components, but the way they are currently selected both
444+ ; by DAGISel and GlobalISel is not susceptible to this issue:
445+ ; * MOVaddrPAC and LOADgotPAC are only emitted when lowering `ptrauth` constants
446+ ; in LLVM IR, so their discriminators are never expressed via blend.
447+ ; * BRA is only emitted for indirect branch, and its address discriminator is
448+ ; always XZR.
449+ ;
450+ ; Furthermore, a few more pseudo instructions have HasPAuth in their predicates,
451+ ; but only have constant discriminator or no discriminator operands at all:
452+ ; LOADgotAUTH and LOADauthptrstatic.
453+ ;
454+ ; The below test cases specify non-default preserve_nonecc calling convention -
455+ ; this is to prevent meaningless divergence between Darwin and ELF targets due
456+ ; to difference in callee-saved register masks specified in call instructions.
457+
458+ define preserve_nonecc i64 @auth_tcreturn_blend_components (ptr %callee , i1 %cond.b ) {
459+ ; DAGISEL-LABEL: name: auth_tcreturn_blend_components
460+ ; DAGISEL: bb.0.entry:
461+ ; DAGISEL-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
462+ ; DAGISEL-NEXT: liveins: $x20, $w0
463+ ; DAGISEL-NEXT: {{ $}}
464+ ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
465+ ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:tcgprnotx16x17 = COPY $x20
466+ ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
467+ ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
468+ ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48
469+ ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:tcgpr64 = COPY [[MOVKXi]]
470+ ; DAGISEL-NEXT: TBZW [[COPY]], 0, %bb.2
471+ ; DAGISEL-NEXT: B %bb.1
472+ ; DAGISEL-NEXT: {{ $}}
473+ ; DAGISEL-NEXT: bb.1.next:
474+ ; DAGISEL-NEXT: successors: %bb.2(0x80000000)
475+ ; DAGISEL-NEXT: {{ $}}
476+ ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]]
477+ ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]]
478+ ; DAGISEL-NEXT: {{ $}}
479+ ; DAGISEL-NEXT: bb.2.exit:
480+ ; DAGISEL-NEXT: AUTH_TCRETURN [[COPY1]], 0, 1, 0, [[COPY2]], csr_aarch64_noneregs, implicit-def dead $x16, implicit-def dead $x17, implicit $sp
481+ ;
482+ ; GISEL-LABEL: name: auth_tcreturn_blend_components
483+ ; GISEL: bb.1.entry:
484+ ; GISEL-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
485+ ; GISEL-NEXT: liveins: $w0, $x20
486+ ; GISEL-NEXT: {{ $}}
487+ ; GISEL-NEXT: [[COPY:%[0-9]+]]:tcgprnotx16x17 = COPY $x20
488+ ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
489+ ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
490+ ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:tcgpr64 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
491+ ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64common = MOVKXi [[LDRXui]], 42, 48
492+ ; GISEL-NEXT: TBZW [[COPY1]], 0, %bb.3
493+ ; GISEL-NEXT: B %bb.2
494+ ; GISEL-NEXT: {{ $}}
495+ ; GISEL-NEXT: bb.2.next:
496+ ; GISEL-NEXT: successors: %bb.3(0x80000000)
497+ ; GISEL-NEXT: {{ $}}
498+ ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[MOVKXi]]
499+ ; GISEL-NEXT: {{ $}}
500+ ; GISEL-NEXT: bb.3.exit:
501+ ; GISEL-NEXT: AUTH_TCRETURN [[COPY]], 0, 1, 42, [[LDRXui]], csr_aarch64_noneregs, implicit-def $x16, implicit-def $x17, implicit $sp
502+ entry:
503+ %addrdisc = load i64 , ptr @discvar
504+ %disc = call i64 @llvm.ptrauth.blend (i64 %addrdisc , i64 42 )
505+ br i1 %cond.b , label %next , label %exit
506+
507+ next:
508+ call void asm sideeffect "nop" , "r" (i64 %disc )
509+ br label %exit
510+
511+ exit:
512+ %result = tail call preserve_nonecc i64 %callee () [ "ptrauth" (i32 1 , i64 %disc ) ]
513+ ret i64 %result
514+ }
515+
516+ define preserve_nonecc i64 @auth_tcreturn_bti_blend_components (ptr %callee , i1 %cond.b ) "branch-target-enforcement" ="true" {
517+ ; DAGISEL-LABEL: name: auth_tcreturn_bti_blend_components
518+ ; DAGISEL: bb.0.entry:
519+ ; DAGISEL-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
520+ ; DAGISEL-NEXT: liveins: $x20, $w0
521+ ; DAGISEL-NEXT: {{ $}}
522+ ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
523+ ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x20
524+ ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
525+ ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
526+ ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48
527+ ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:tcgprnotx16x17 = COPY [[MOVKXi]]
528+ ; DAGISEL-NEXT: TBZW [[COPY]], 0, %bb.2
529+ ; DAGISEL-NEXT: B %bb.1
530+ ; DAGISEL-NEXT: {{ $}}
531+ ; DAGISEL-NEXT: bb.1.next:
532+ ; DAGISEL-NEXT: successors: %bb.2(0x80000000)
533+ ; DAGISEL-NEXT: {{ $}}
534+ ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]]
535+ ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]]
536+ ; DAGISEL-NEXT: {{ $}}
537+ ; DAGISEL-NEXT: bb.2.exit:
538+ ; DAGISEL-NEXT: [[COPY4:%[0-9]+]]:tcgprx16x17 = COPY [[COPY1]]
539+ ; DAGISEL-NEXT: AUTH_TCRETURN_BTI [[COPY4]], 0, 1, 0, [[COPY2]], csr_aarch64_noneregs, implicit-def dead $x16, implicit-def dead $x17, implicit $sp
540+ ;
541+ ; GISEL-LABEL: name: auth_tcreturn_bti_blend_components
542+ ; GISEL: bb.1.entry:
543+ ; GISEL-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
544+ ; GISEL-NEXT: liveins: $w0, $x20
545+ ; GISEL-NEXT: {{ $}}
546+ ; GISEL-NEXT: [[COPY:%[0-9]+]]:tcgprx16x17 = COPY $x20
547+ ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
548+ ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
549+ ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:tcgprnotx16x17 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
550+ ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64common = MOVKXi [[LDRXui]], 42, 48
551+ ; GISEL-NEXT: TBZW [[COPY1]], 0, %bb.3
552+ ; GISEL-NEXT: B %bb.2
553+ ; GISEL-NEXT: {{ $}}
554+ ; GISEL-NEXT: bb.2.next:
555+ ; GISEL-NEXT: successors: %bb.3(0x80000000)
556+ ; GISEL-NEXT: {{ $}}
557+ ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[MOVKXi]]
558+ ; GISEL-NEXT: {{ $}}
559+ ; GISEL-NEXT: bb.3.exit:
560+ ; GISEL-NEXT: AUTH_TCRETURN_BTI [[COPY]], 0, 1, 42, [[LDRXui]], csr_aarch64_noneregs, implicit-def $x16, implicit-def $x17, implicit $sp
561+ entry:
562+ %addrdisc = load i64 , ptr @discvar
563+ %disc = call i64 @llvm.ptrauth.blend (i64 %addrdisc , i64 42 )
564+ br i1 %cond.b , label %next , label %exit
565+
566+ next:
567+ call void asm sideeffect "nop" , "r" (i64 %disc )
568+ br label %exit
569+
570+ exit:
571+ %result = tail call preserve_nonecc i64 %callee () [ "ptrauth" (i32 1 , i64 %disc ) ]
572+ ret i64 %result
573+ }
574+
575+ define preserve_nonecc i64 @blra_blend_components (ptr %callee , i1 %cond.b ) {
576+ ; DAGISEL-LABEL: name: blra_blend_components
577+ ; DAGISEL: bb.0.entry:
578+ ; DAGISEL-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
579+ ; DAGISEL-NEXT: liveins: $x20, $w0
580+ ; DAGISEL-NEXT: {{ $}}
581+ ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
582+ ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY $x20
583+ ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
584+ ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
585+ ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48
586+ ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[MOVKXi]]
587+ ; DAGISEL-NEXT: TBZW [[COPY]], 0, %bb.2
588+ ; DAGISEL-NEXT: B %bb.1
589+ ; DAGISEL-NEXT: {{ $}}
590+ ; DAGISEL-NEXT: bb.1.next:
591+ ; DAGISEL-NEXT: successors: %bb.2(0x80000000)
592+ ; DAGISEL-NEXT: {{ $}}
593+ ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]]
594+ ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]]
595+ ; DAGISEL-NEXT: {{ $}}
596+ ; DAGISEL-NEXT: bb.2.exit:
597+ ; DAGISEL-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
598+ ; 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
599+ ; DAGISEL-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
600+ ; DAGISEL-NEXT: [[COPY4:%[0-9]+]]:gpr64sp = COPY $x0
601+ ; DAGISEL-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY4]], 123, 0
602+ ; DAGISEL-NEXT: $x0 = COPY [[ADDXri]]
603+ ; DAGISEL-NEXT: RET_ReallyLR implicit $x0
604+ ;
605+ ; GISEL-LABEL: name: blra_blend_components
606+ ; GISEL: bb.1.entry:
607+ ; GISEL-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
608+ ; GISEL-NEXT: liveins: $w0, $x20
609+ ; GISEL-NEXT: {{ $}}
610+ ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64noip = COPY $x20
611+ ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w0
612+ ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar
613+ ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar)
614+ ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64common = MOVKXi [[LDRXui]], 42, 48
615+ ; GISEL-NEXT: TBZW [[COPY1]], 0, %bb.3
616+ ; GISEL-NEXT: B %bb.2
617+ ; GISEL-NEXT: {{ $}}
618+ ; GISEL-NEXT: bb.2.next:
619+ ; GISEL-NEXT: successors: %bb.3(0x80000000)
620+ ; GISEL-NEXT: {{ $}}
621+ ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[MOVKXi]]
622+ ; GISEL-NEXT: {{ $}}
623+ ; GISEL-NEXT: bb.3.exit:
624+ ; GISEL-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp
625+ ; GISEL-NEXT: BLRA [[COPY]], 1, 42, [[LDRXui]], csr_aarch64_noneregs, implicit-def $x16, implicit-def $x17, implicit-def $lr, implicit $sp, implicit-def $x0
626+ ; GISEL-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp
627+ ; GISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64sp = COPY $x0
628+ ; GISEL-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY2]], 123, 0
629+ ; GISEL-NEXT: $x0 = COPY [[ADDXri]]
630+ ; GISEL-NEXT: RET_ReallyLR implicit $x0
631+ entry:
632+ %addrdisc = load i64 , ptr @discvar
633+ %disc = call i64 @llvm.ptrauth.blend (i64 %addrdisc , i64 42 )
634+ br i1 %cond.b , label %next , label %exit
635+
636+ next:
637+ call void asm sideeffect "nop" , "r" (i64 %disc )
638+ br label %exit
639+
640+ exit:
641+ %tmp = call preserve_nonecc i64 %callee () [ "ptrauth" (i32 1 , i64 %disc ) ]
642+ ; Prevent tail call.
643+ %result = add i64 %tmp , 123
644+ ret i64 %result
645+ }
0 commit comments