Clang optimizing an infinite loop

Hello everyone,

for testing our code I wanted to create an infinite loop with Clang, so I wrote the most basic infinite loop I came up with:

void Sample()

{

while(true);

}

To my surprise Clang generated the following assembly code:

.def “?Sample@@YAXXZ”;

.scl 2;

.type 32;

.endef

.section .text,“xr”,one_only,“?Sample@@YAXXZ

.globl “?Sample@@YAXXZ” # – Begin function ?Sample@@YAXXZ

.p2align 4, 0x90

“?Sample@@YAXXZ”: # @“?Sample@@YAXXZ

.Lfunc_begin4:

.cv_func_id 6

%bb.0:

nop # avoids zero-length function

.Lfunc_end4:

– End function

Which ended in an access violation D:

Why was Clang doing that? Is it because of some loop optimization since the body of the loop is empty and nothing else happens in the loop? :0

But why was it missing the “ret” instruction then?

The full command line without include directories is:
1>clang version 13.0.0 (https://github.com/llvm/llvm-project.git 5f500d73cd1aaff4c9ab2fd5c327c2d5ca9ae5c9)

1>Target: x86_64-pc-windows-msvc

1>Thread model: posix

1> “clang-cl.exe” -cc1 -triple x86_64-pc-windows-msvc19.28.29912 -S -disable-free -disable-llvm-verifier -discard-value-names -main-file-name CMException.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu skylake -target-feature +fsgsbase -mllvm -x86-asm-syntax=intel -mllvm -treat-scalable-fixed-error-as-warning -D_MT -flto-visibility-public-std --dependent-lib=libcmt --dependent-lib=oldnames -stack-protector 2 -fcxx-exceptions -fexceptions -fexternc-nounwind -fms-volatile -fdefault-calling-conv=cdecl -fdiagnostics-format msvc -gno-column-info -gcodeview -debug-info-kind=limited -v -ffunction-sections -D WIN32 -D NTSYSAD_CM -D CODEMODULE -D _CONSOLE -D _UNICODE -D NDEBUG -D _CRT_SECURE_NO_WARNINGS -D _CRT_USE_BUILTIN_OFFSETOF -D NOMINMAX -D _UNICODE -D UNICODE -O2 -Wall -Wno-error -Wno-unused-command-line-argument -Wno-microsoft-cast -Wno-writable-strings -Wno-microsoft-enum-forward-reference -Wno-invalid-token-paste -fdeprecated-macro -ferror-limit 3000 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.28.29912 -std=c++17 -fdelayed-template-parsing -fno-caret-diagnostics -vectorize-loops -vectorize-slp -faddrsig -o “x64\Release\CMException.asm” -x c++ CMException.cpp

Thank you for any help in advance!

Kind regards

Björn

Hi,

'Clang' isn't actually doing anything here, clang emits LLVM IR, which is then optimised by LLVM. In general, if you have questions about optimisations you're better off asking them on llvm-dev. That said:

Infinite loops without side effects in C are undefined behaviour. This is because proving that a loop terminate is probably the most famous example of a non-computable problem and so optimisers are left free to assume that loops terminate. Specifically in N1570, Section 6.8.5, paragraph 6, states:

> An iteration statement whose controlling expression is not a constant expression) that performs no input/output operations, does not access volatile objects, and performs no synchronization or atomic operations in its body, controlling expression, or (in the case of a for statement) its expression, may be assumed by the implementation to terminate.

This means that if the optimiser encounters an infinite loop it is free to assume that it is unreachable and elide it entirely (or replace it with a trap, or erase your hard disk).

David

Hey,

Thank you for the explanation! That explains everything.

Kind regards
Björn