Issue 151104
Summary Why does LLVM generate select ... -1 ... before operator new[] when array size < 1
Labels new issue
Assignees
Reporter 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.
https://github.com/llvm/llvm-project/blob/2780b8f22058b35a8e70045858b87a1966df8df3/clang/lib/CodeGen/CGExprCXX.cpp#L874-L878
https://github.com/llvm/llvm-project/blob/2780b8f22058b35a8e70045858b87a1966df8df3/clang/lib/CodeGen/CGExprCXX.cpp#L955-L962

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?

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to