Skip to content

Why does LLVM generate select ... -1 ... before operator new[] when array size < 1 #151104

@guoxin049

Description

@guoxin049

When compiling the following code targeting AArch64 with Clang/LLVM, I observed that the generated IR includes a select instruction that yields -1 when the array size is less than 1:

__attribute__((noinline)) uint32_t Get() {
    return 0;
}

uintptr_t Test() {
    const uint32_t len = Get();
    auto buf = new uint8_t[len]{0};
    return (uintptr_t)buf;
}

The IR:

%conv = zext i32 %0 to i64
%1 = icmp ult i64 %conv, 1
%2 = select i1 %1, i64 -1, i64 %conv
%call1 = call noalias noundef nonnull ptr @operator new[](unsigned long)(i64 noundef %2)

The ASM:

Get():
        mov     w0, wzr
        ret

Test():
        stp     x29, x30, [sp, #-32]!
        str     x19, [sp, #16]
        mov     x29, sp
        mov     x0, #-1
        bl      operator new[](unsigned long)
        mov     w1, wzr
        mov     x2, #-2
        mov     x19, x0
        strb    wzr, [x0], #1
        bl      memset
        mov     x0, x19
        ldr     x19, [sp, #16]
        ldp     x29, x30, [sp], #32
        ret

This seems to be generated from EmitCXXNewAllocSize in CGExprCXX.cpp, where -1 is used if the element count is less than 1.

if (minElements) {
// Don't allow allocation of fewer elements than we have initializers.
if (!hasOverflow) {
hasOverflow = CGF.Builder.CreateICmpULT(numElements,
llvm::ConstantInt::get(CGF.SizeTy, minElements));

// If we had any possibility of dynamic overflow, make a select to
// overwrite 'size' with an all-ones value, which should cause
// operator new to throw.
if (hasOverflow)
size = CGF.Builder.CreateSelect(hasOverflow,
llvm::Constant::getAllOnesValue(CGF.SizeTy),
size);
}

Why is -1 used in this case?
Why -1 was chosen instead of, say, 0?
Does this implementation risk triggering excessive or unintended memory allocations under certain conditions?

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:codegenIR generation bugs: mangling, exceptions, etc.clang:frontendLanguage frontend issues, e.g. anything involving "Sema"questionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions