diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -79,6 +79,7 @@ unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { const MachineBasicBlock &MBB = *MI.getParent(); const MachineFunction *MF = MBB.getParent(); + const Function &F = MF->getFunction(); const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo(); { @@ -127,10 +128,21 @@ NumBytes = 4; break; case TargetOpcode::PATCHABLE_FUNCTION_ENTER: + // If `patchable-function-entry` is set, PATCHABLE_FUNCTION_ENTER + // instructions are expanded to the specified number of NOPs. Otherwise, + // they are expanded to 36-byte XRay sleds. + NumBytes = + F.getFnAttributeAsParsedInteger("patchable-function-entry", 9) * 4; + break; case TargetOpcode::PATCHABLE_FUNCTION_EXIT: + case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL: // An XRay sled can be 4 bytes of alignment plus a 32-byte block. NumBytes = 36; break; + case TargetOpcode::PATCHABLE_EVENT_CALL: + // EVENT_CALL XRay sleds are exactly 6 instructions long (no alignment). + NumBytes = 24; + break; case AArch64::SPACE: NumBytes = MI.getOperand(1).getImm(); diff --git a/llvm/test/CodeGen/AArch64/branch-relax-xray.ll b/llvm/test/CodeGen/AArch64/branch-relax-xray.ll --- a/llvm/test/CodeGen/AArch64/branch-relax-xray.ll +++ b/llvm/test/CodeGen/AArch64/branch-relax-xray.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=aarch64-unknown-linux-gnu -aarch64-tbz-offset-bits=4 -aarch64-cbz-offset-bits=4 < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-unknown-linux-gnu -aarch64-tbz-offset-bits=4 -aarch64-cbz-offset-bits=3 < %s | FileCheck %s ;; Check that branch relaxation accounts for the size of xray EXIT sleds ;; Note that TAIL_CALL sleds don't exist on AArch64 and don't need a test. @@ -38,5 +38,83 @@ ret void } +;; Check that branch relaxation accounts for the size of xray EVENT sleds +define void @customevent(i1 zeroext %0, ptr nocapture noundef readonly %e1, i64 noundef %s1, ptr nocapture noundef readonly %e2, i64 noundef %s2) "function-instrument"="xray-always" { +; CHECK-LABEL: customevent: +; CHECK-NEXT: .Lfunc_begin1: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: .Lxray_sled_{{[0-9]+}}: +; CHECK: cbnz +; CHECK-SAME: [[FALLTHROUGH_2:.LBB[0-9_]+]] +; CHECK-NEXT: b +; CHECK-SAME: [[OUT_OF_RANGE_2:.LBB[0-9_]+]] +; CHECK-NEXT: [[FALLTHROUGH_2]]: +; CHECK-SAME: // %end1 +; CHECK-NEXT: .Lxray_sled_{{[0-9]+}}: +; CHECK-NEXT: Begin XRay custom event +; CHECK: bl __xray_CustomEvent +; CHECK: End XRay custom event +; CHECK-NEXT: [[OUT_OF_RANGE_2]]: +; CHECK-SAME: // %end2 +; CHECK-NEXT: .Lxray_sled_{{[0-9]+}}: +; CHECK-NEXT: Begin XRay custom event +; CHECK: bl __xray_CustomEvent +; CHECK: End XRay custom event +; CHECK: .Ltmp +; CHECK-NEXT: ret +entry: + br i1 %0, label %end1, label %end2 + +end1: + call void @llvm.xray.customevent(ptr %e1, i64 %s1) + br label %end2 + +end2: + tail call void @llvm.xray.customevent(ptr %e2, i64 %s2) + ret void +} + +;; Check that branch relaxation accounts for the size of xray TYPED_EVENT sleds +define void @typedevent(i1 zeroext %0, i64 noundef %type, ptr nocapture noundef readonly %event, i64 noundef %size) "function-instrument"="xray-always" { +; CHECK-LABEL: typedevent: +; CHECK-NEXT: .Lfunc_begin2: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: .p2align 2 +; CHECK-NEXT: .Lxray_sled_{{[0-9]+}}: +; CHECK: cbnz +; CHECK-SAME: [[FALLTHROUGH_3:.LBB[0-9_]+]] +; CHECK-NEXT: b +; CHECK-SAME: [[OUT_OF_RANGE_3:.LBB[0-9_]+]] +; CHECK-NEXT: [[FALLTHROUGH_3]]: +; CHECK-SAME: // %end1 +; CHECK-NEXT: .Lxray_sled_{{[0-9]+}}: +; CHECK-NEXT: Begin XRay typed event +; CHECK: bl __xray_TypedEvent +; CHECK: End XRay typed event +; CHECK-NEXT: [[OUT_OF_RANGE_3]]: +; CHECK-SAME: // %end2 +; CHECK-NEXT: .Lxray_sled_{{[0-9]+}}: +; CHECK-NEXT: Begin XRay typed event +; CHECK: bl __xray_TypedEvent +; CHECK: End XRay typed event +; CHECK: .Ltmp +; CHECK-NEXT: ret +entry: + br i1 %0, label %end1, label %end2 + +end1: + call void @llvm.xray.typedevent(i64 %type, ptr %event, i64 %size) + br label %end2 + +end2: + tail call void @llvm.xray.typedevent(i64 %size, ptr %event, i64 %type) + ret void +} + +declare void @llvm.xray.customevent(ptr, i64) +declare void @llvm.xray.typedevent(i64, ptr, i64) declare i32 @bar() declare i32 @baz() \ No newline at end of file