Skip to content

Consider a higher-level representation for checked memory functions #1051

Open
@smeenai

Description

@smeenai

__memcpy_chk and __memset_chk are libc functions to support FORTIFY (the bionic docs are a good introduction for the curious). In addition to a count parameter describing how many bytes to copy, they also take a size parameter for the size of the destination buffer, and the function fails at runtime if the count is greater than the size.

Clang implements builtins which call the unchecked functions if the count is known to be <= the size at compile time and call the checked functions otherwise. See https://godbolt.org/z/89dzxadjo for some examples. In #1032, ClangIR implements __builtin___memcpy_chk using the same strategy (and __builtin___memset_chk will follow shortly).

We can potentially instead extend cir.libc.mem* to take in additional information for the checked variants, e.g.

cir.libc.memcpy checked %1 bytes from %2 to %3 of size %4 bytes

This would potentially allow us to constant-fold more cases after CIR optimizations. LLVM has a TargetLibraryInfo hook for __memcpy_chk and can fold some cases that Clang misses, but it also doesn't catch all the cases it could (as seen in the above Godbolt link, where __memcpy_chk(dst, src, n, n) gets simplified but __memcpy_chk(dst, src, n, n + 1) doesn't). It should be pretty doable to fix that though, and I don't know if we'll gain much from an optimization standpoint with the higher-level ClangIR optimization, but it's a nicer design and keeps more information around, which can always be useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    IR designConsiderations around the design of ClangIR

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions