@@ -511,3 +511,212 @@ exit:
511
511
%resigned = call i64 @llvm.ptrauth.resign (i64 %addr , i32 2 , i64 %auth.disc , i32 3 , i64 %sign.disc )
512
512
ret i64 %resigned
513
513
}
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