| Issue |
52851
|
| Summary |
LLVM fails to remove bounds check on loops over pointers
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
AngelicosPhosphoros
|
I expected that LLVM would remove bounds check on this code:
```cpp
#include <cstddef>
void do_checks(const int* begin, const size_t len){
size_t idx = 0;
const auto end = begin + len;
for (const int* it = begin; it!=end; ++it, ++idx){
if (idx < len){
// Do something useful
}
else
{
throw 5;
}
}
}
```
But it doesn't:
```llvm
@_ZTIi = external dso_local constant i8*
define dso_local void @_Z9do_checksPKim(i32* readnone %0, i64 %1) local_unnamed_addr #0 !dbg !15 {
call void @llvm.dbg.value(metadata i32* %0, metadata !27, metadata !DIExpression()), !dbg !34
call void @llvm.dbg.value(metadata i64 %1, metadata !28, metadata !DIExpression()), !dbg !34
call void @llvm.dbg.value(metadata i64 0, metadata !29, metadata !DIExpression()), !dbg !34
call void @llvm.dbg.value(metadata !DIArgList(i32* %0, i64 %1), metadata !30, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 4, DW_OP_mul, DW_OP_plus, DW_OP_stack_value)), !dbg !34
call void @llvm.dbg.value(metadata i32* %0, metadata !32, metadata !DIExpression()), !dbg !35
call void @llvm.dbg.value(metadata i64 0, metadata !29, metadata !DIExpression()), !dbg !34
%3 = icmp eq i64 %1, 0, !dbg !36
br i1 %3, label %4, label %5, !dbg !38
4: ; preds = %5, %2
ret void, !dbg !39
5: ; preds = %2
%6 = shl nsw i64 %1, 2, !dbg !38
%7 = add i64 %6, -4, !dbg !38
%8 = lshr exact i64 %7, 2, !dbg !38
%9 = icmp ult i64 %8, %1, !dbg !38
call void @llvm.dbg.value(metadata i32* undef, metadata !32, metadata !DIExpression()), !dbg !35
call void @llvm.dbg.value(metadata i64 undef, metadata !29, metadata !DIExpression()), !dbg !34
br i1 %9, label %4, label %10, !dbg !40
10: ; preds = %5
%11 = tail call i8* @__cxa_allocate_exception(i64 4) #2, !dbg !42
%12 = bitcast i8* %11 to i32*, !dbg !42
store i32 5, i32* %12, align 16, !dbg !42, !tbaa !45
tail call void @__cxa_throw(i8* %11, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3, !dbg !42
unreachable, !dbg !42
}
declare dso_local i8* @__cxa_allocate_exception(i64) local_unnamed_addr
declare dso_local void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
attributes #0 = { mustprogress uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
attributes #2 = { nounwind }
attributes #3 = { noreturn }
```
[godbolt link](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:2,endLineNumber:15,positionColumn:2,positionLineNumber:15,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'%23include+%3Ccstddef%3E%0A%0Avoid+do_checks(const+int*+begin,+const+size_t+len)%7B%0A++++size_t+idx+%3D+0%3B%0A++++const+auto+end+%3D+begin+%2B+len%3B%0A++++for+(const+int*+it+%3D+begin%3B+it!!%3Dend%3B+%2B%2Bit,+%2B%2Bidx)%7B%0A++++++++if+(idx+%3C+len)%7B%0A++++++++++++//+Do+something+useful%0A++++++++%7D%0A++++++++else%0A++++++++%7B%0A++++++++++++throw+5%3B%0A++++++++%7D%0A++++%7D%0A%7D'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:31.621243885394836,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang1300,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'1',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:2,lang:c%2B%2B,libs:!(),options:'-O3',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1,tree:'1'),l:'5',n:'0',o:'x86-64+clang+13.0.0+(C%2B%2B,+Editor+%231,+Compiler+%232)',t:'0')),k:35.045422781271846,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:ir,i:(editorId:1,fontScale:14,fontUsePx:'0',j:2,selection:(endColumn:29,endLineNumber:43,positionColumn:1,positionLineNumber:1,selectionStartColumn:29,selectionStartLineNumber:43,startColumn:1,startLineNumber:1)),l:'5',n:'0',o:'LLVM+IR+Viewer+x86-64+clang+13.0.0(Editor+%231,+Compiler+%232)',t:'0')),k:33.33333333333333,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)
It affects real-world code like this:
```cpp
size_t idx = 0;
for (auto& ref : v){
v.at(idx);
}
```
or in Rust
```rust
for (i, v) in arr.enumerate(){
let prev_chunk = &arr[..i];
}
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs