return isUnscaledLdSt(MI.getOpcode());
}
+bool AArch64InstrInfo::isTailCall(const MachineInstr &Inst) const
+{
+ switch (Inst.getOpcode()) {
+ case AArch64::TCRETURNdi:
+ case AArch64::TCRETURNri:
+ return true;
+ default:
+ return false;
+ }
+}
+
// Is this a candidate for ld/st merging or pairing? For example, we don't
// touch volatiles or load/stores that have a hint to avoid pair formation.
bool AArch64InstrInfo::isCandidateToMergeOrPair(MachineInstr &MI) const {
/// Return true if this is an unscaled load/store.
bool isUnscaledLdSt(MachineInstr &MI) const;
+ bool isTailCall(const MachineInstr &Inst) const override;
+
static bool isPairableLdStInst(const MachineInstr &MI) {
switch (MI.getOpcode()) {
default:
--- /dev/null
+; RUN: llc -filetype=asm -o - -mtriple=aarch64-linux-gnu < %s | FileCheck %s\r
+\r
+define i32 @callee() nounwind noinline uwtable "function-instrument"="xray-always" {\r
+; CHECK: .p2align 2\r
+; CHECK-LABEL: .Lxray_sled_0:\r
+; CHECK-NEXT: b #32\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-LABEL: .Ltmp0:\r
+ ret i32 0\r
+; CHECK-NEXT: mov w0, wzr\r
+; CHECK-NEXT: .p2align 2\r
+; CHECK-LABEL: .Lxray_sled_1:\r
+; CHECK-NEXT: b #32\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-LABEL: .Ltmp1:\r
+; CHECK-NEXT: ret\r
+}\r
+; CHECK: .p2align 4\r
+; CHECK-NEXT: .xword .Lxray_synthetic_0\r
+; CHECK-NEXT: .section xray_instr_map,{{.*}}\r
+; CHECK-LABEL: Lxray_synthetic_0:\r
+; CHECK: .xword .Lxray_sled_0\r
+; CHECK: .xword .Lxray_sled_1\r
+\r
+define i32 @caller() nounwind noinline uwtable "function-instrument"="xray-always" {\r
+; CHECK: .p2align 2\r
+; CHECK-LABEL: .Lxray_sled_2:\r
+; CHECK-NEXT: b #32\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-LABEL: .Ltmp2:\r
+; CHECK: .p2align 2\r
+; CHECK-LABEL: .Lxray_sled_3:\r
+; CHECK-NEXT: b #32\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-NEXT: nop\r
+; CHECK-LABEL: .Ltmp3:\r
+ %retval = tail call i32 @callee()\r
+; CHECK: b callee\r
+ ret i32 %retval\r
+}\r
+; CHECK: .p2align 4\r
+; CHECK-NEXT: .xword .Lxray_synthetic_1\r
+; CHECK-NEXT: .section xray_instr_map,{{.*}}\r
+; CHECK-LABEL: Lxray_synthetic_1:\r
+; CHECK: .xword .Lxray_sled_2\r
+; CHECK: .xword .Lxray_sled_3\r