[LLVMdev] clang : assert ignored with -O1 ?!

Frédéric Heitzmann frederic.heitzmann at gmail.com
Fri Nov 30 13:12:57 PST 2012


Hi all,

I work on an embedded target, in which function assert is an infinite 
while(1) loop.
It is a common technique to set a breakpoint in the loop, in case some 
error occurs while debugging.

It looks like clang simply *removes* any call to assert when compiling 
with -O1 (not -O0).
note 1 : the name 'assert' is not the problem.
note 2 : if the while(1) loop has some side effect, like increasing a 
global variable, it is not removed.

=> Is it a normal behaviour of -O1 ? I did not find any documentation 
about it.

--
Fred
--

$ cat tassert.c
int loop=0;
void infloop_assert(){
   while(1){
//    loop++;    //uncomment me
   }
}

int test(int x){
   if (x)
     infloop_assert();    << call here

   return 1;
}

######"
$ clang -O0 -emit-llvm -S -c tassert.c -o tassert.ll && cat tassert.ll

; ModuleID = 'tassert.c'
target datalayout = 
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
target triple = "i386-pc-linux-gnu"

@loop = global i32 0, align 4

define void @infloop_assert() nounwind {        <<<< definition here
entry:
   br label %while.body

while.body:                                       ; preds = %entry, 
%while.body
   br label %while.body

return:                                           ; No predecessors!
   ret void
}

define i32 @test(i32 %x) nounwind {
entry:
   %x.addr = alloca i32, align 4
   store i32 %x, i32* %x.addr, align 4
   %0 = load i32* %x.addr, align 4
   %tobool = icmp ne i32 %0, 0
   br i1 %tobool, label %if.then, label %if.end

if.then:                                          ; preds = %entry
   call void @infloop_assert()     <<<< call here
   br label %if.end

if.end:                                           ; preds = %if.then, %entry
   ret i32 1
}

######"
$ clang -O1 -emit-llvm -S -c tassert.c -o tassert.ll && cat tassert.ll
; ModuleID = 'tassert.c'
target datalayout = 
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
target triple = "i386-pc-linux-gnu"

@loop = global i32 0, align 4

define void @infloop_assert() noreturn nounwind readnone { <<<< 
definition here, slightly different
entry:
   br label %while.body

while.body:                                       ; preds = %entry, 
%while.body
   br label %while.body
}

define i32 @test(i32 %x) nounwind readnone {
entry:
   ret i32 1                     <<<< where did it go ?!?!
}




More information about the llvm-dev mailing list