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