Skip to content

Add builtin/intrinsic to get current instruction pointer? #138272

@nikic

Description

@nikic

The linux kernel has a macro like this:

#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })

This is used to get the current instruction pointer for error reporting purposes. It is not used to perform any control flow transitions to the label.

This usage is problematic, because it violates LLVM's requirements for blockaddress usage:

This value only has defined behavior when used as an operand to the ‘indirectbr’ or for comparisons against null. Pointer equality tests between labels addresses results in undefined behavior — though, again, comparison against null is ok, and no label is equal to the null pointer. This may be passed around as an opaque pointer sized value as long as the bits are not inspected. This allows ptrtoint and arithmetic to be performed on these values so long as the original value is reconstituted before the indirectbr instruction.

Basically, LLVM only actually supports block labels when used together with computed goto. If block labels are used without computed goto, the label can be optimized away and replaced with a dummy address. We have just enough hacks to prevent this from happening in common cases, but I feel like this is architecturally not sustainable.

I am wondering if it would make sense to add something like __builtin_instruction_pointer() / @llvm.instruction.pointer() to obtain the current instruction pointer? Where "current" is necessarily a best-effort approximation.

@nathanchance @kees Would that be suitable for the kernel use case?

cc @efriedma-quic

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"enhancementImproving things as opposed to bug fixing, e.g. new or missing feature

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions