# Gcc/clang -O1 bug

**URL:** <https://discourse.ats-lang.org/t/gcc-clang-o1-bug/584>\
**Category:** Google Group\
**Created:** [May 17, 2014, 5:14am UTC](https://discourse.ats-lang.org/t/gcc-clang-o1-bug/584 "2014-05-17T05:14:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [May 17, 2014, 5:14am UTC](https://discourse.ats-lang.org/t/gcc-clang-o1-bug/584/1 "2014-05-17T05:14:40Z")

</div>

I encountered a gcc/clang -O1 (not -O2) optimization bug that really  
shocked me a bit.

In the code below, if the following line is dropped,

val () = ptr\_volatile (p\_nseq)

then the gcc/clang (with -O1) somehow thinks that the content of nseq is  
never modified. As a consequence, the function always returns 0. If -O1  
is dropped or changed to -O0, then the compiled code works fine. I also  
tried tcc and noticed that it can compile the following code correctly.

This is a shock because the involved code is so simple!

To see what happens, you can try out the code at:

> **[githwxi/ATS-Postiats-contrib](https://github.com/githwxi/ATS-Postiats-contrib/tree/master/projects/SMALL/M-N-K-game/Part1)**
>
> ATS-Postiats-contrib is primarily for packages contributed to ATS-Postiats - githwxi/ATS-Postiats-contrib

implement  
board\_dirmax  
(  
board, pid, dir, i, j  
) = let  
//  
var nseq: int = 0  
val p\_nseq = addr@nseq  
//  
fun loop  
(  
i: int, j: int  
) : void = let  
//  
val pid2 = board[i, j]  
//  
in  
if pid = pid2  
then let  
val n = $UN.ptr1\_get (p\_nseq)  
val () = $UN.ptr1\_set (p\_nseq, n + 1)  
val (i, j) = dirnext (dir, i, j)  
in  
loop (i, j)  
end // end of [then]  
// end of [if]  
end // end of [loop]  
//  
val () = ptr\_volatile (p\_nseq) // -O1 bug if omitted  
val () = try loop (i, j) with ~MatrixSubscriptExn () =\> ()  
//  
in  
$UN.cast{intGte(0)}(nseq)  
end // end of [board\_dirmax]

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [May 17, 2014, 6:13pm UTC](https://discourse.ats-lang.org/t/gcc-clang-o1-bug/584/2 "2014-05-17T18:13:46Z")

</div>

Okay, I made the email setting change.On Saturday, May 17, 2014 4:40:45 AM UTC-4, Sean Leather wrote:

> After off-list discussion (my apologies, but see remark at end), Hongwei  
> shared the generated C for this example. Follow the tmpref188 variable.  
> It does indeed look like a bug in GCC.
> 
> extern atstype\_int  
> \_057\_home\_057\_hwxi\_057\_research\_057\_Postiats\_055\_contrib\_057\_git\_057\_projects\_057\_SMALL\_057\_M\_055\_N\_055\_K\_055\_game\_057\_Part1\_057\_game\_board\_056\_dats\_\_board\_dirmax  
> (atstype\_ptrk arg0, atstype\_int arg1, atstype\_boxed arg2, atstype\_int arg3  
> , atstype\_int arg4) {  
> atstype\_int tmpret187 ;  
> atstype\_int tmpref188 ;  
> ;  
> ;  
> atstype\_exnconptr tmp270 ;  
> \_\_patsflab\_board\_dirmax: # 5637 “game\_board\_dats.c” (tmpref188 = 0) ;  
> ATSLIB\_056\_prelude\_\_ptr\_volatile((&(tmpref188))) ;  
> do {  
> int flag ;  
> atsexnframe\_ptr frame ;  
> atsexnframe\_ptr \*framep ;  
> frame = alloca(sizeof(atsexnframe\_t)) ;  
> framep = my\_atsexnframe\_getref() ;  
> my\_atsexnframe\_enter(frame, framep) ;  
> flag = \_setjmp (frame-\>  
> env) ;  
> if (flag==0) {  
> loop\_91(arg0, arg1, arg2, (&(tmpref188)), arg3, arg4) ;  
> my\_atsexnframe\_leave(framep) ;  
> }  
> else {  
> tmp270 = (_framep)-\>  
> exn ;  
> my\_atsexnframe\_leave(framep) ;  
> do {  
> ;  
> \_\_atstmplab23: if (!(((tmp270)==(void_)(&(  
> ATSLIB\_056\_prelude\_\_MatrixSubscriptExn))))) {  
> atsruntime\_raise(tmp270) ;  
> }  
> \_\_atstmplab24: # 5680 “game\_board\_dats.c” ;  
> break ;  
> }  
> while (0) ;  
> }  
> }  
> while(0) ;  
> (tmpret187 = ((atstype\_int)tmpref188)) ;  
> return (tmpret187) ;
> 
> }
> 
> About the off-list reply, this Google Group is apparently set up to have  
> recipients post their replies “to the author of the message only”. I  
> recommend changing the setting to “to the entire group”. On the group  
> management page, I believe you can set this in Settings → Email options →   
> Post replies.

---

<div class="post-metadata">

**Author:** ![Ian\_Denhardt](https://avatars.discourse-cdn.com/v4/letter/i/7feea3/32.png) [@Ian\_Denhardt](https://discourse.ats-lang.org/u/Ian_Denhardt)\
**Post date:** [May 19, 2014, 6:03am UTC](https://discourse.ats-lang.org/t/gcc-clang-o1-bug/584/3 "2014-05-19T06:03:03Z")

</div>

Would it be possible for you (or Hongwei) to attach the generated C source as a  
separate file? I’d like to have a look at this, but it’s come through a bit  
mangled in the email.

-Ian

Quoting Sean Leather (2014-05-17 04:40:45)

[signature.asc](https://us1.discourse-cdn.com/flex019/uploads/ats_lang/original/1X/a81eddda43ffb2a8e2b85a4bc569d6a20875e29d.asc) (836 Bytes)

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [May 17, 2014, 6:49am UTC](https://discourse.ats-lang.org/t/gcc-clang-o1-bug/584/4 "2014-05-17T06:49:24Z")

</div>

gcc-4.6.3 was used.On Saturday, May 17, 2014 1:14:40 AM UTC-4, gmhwxi wrote:

> I encountered a gcc/clang -O1 (not -O2) optimization bug that really  
> shocked me a bit.
> 
> In the code below, if the following line is dropped,
> 
> val () = ptr\_volatile (p\_nseq)
> 
> then the gcc/clang (with -O1) somehow thinks that the content of nseq is  
> never modified. As a consequence, the function always returns 0. If -O1  
> is dropped or changed to -O0, then the compiled code works fine. I also  
> tried tcc and noticed that it can compile the following code correctly.
> 
> This is a shock because the involved code is so simple!
> 
> To see what happens, you can try out the code at:
> 
> [https://github.com/githwxi/ATS-Postiats-contrib/tree/master/projects/SMALL/M-N-K-game/Part1](https://github.com/githwxi/ATS-Postiats-contrib/tree/master/projects/SMALL/M-N-K-game/Part1)
> 
> implement  
> board\_dirmax  
> (  
> board, pid, dir, i, j  
> ) = let  
> //  
> var nseq: int = 0  
> val p\_nseq = addr@nseq  
> //  
> fun loop  
> (  
> i: int, j: int  
> ) : void = let  
> //  
> val pid2 = board[i, j]  
> //  
> in  
> if pid = pid2  
> then let  
> val n = $UN.ptr1\_get (p\_nseq)  
> val () = $UN.ptr1\_set (p\_nseq, n + 1)  
> val (i, j) = dirnext (dir, i, j)  
> in  
> loop (i, j)  
> end // end of [then]  
> // end of [if]  
> end // end of [loop]  
> //  
> val () = ptr\_volatile (p\_nseq) // -O1 bug if omitted  
> val () = try loop (i, j) with ~MatrixSubscriptExn () =\> ()  
> //  
> in  
> $UN.cast{intGte(0)}(nseq)  
> end // end of [board\_dirmax]

---

<div class="post-metadata">

**Author:** ![Sean\_Leather](https://avatars.discourse-cdn.com/v4/letter/s/8e8cbc/32.png) [@Sean\_Leather](https://discourse.ats-lang.org/u/Sean_Leather)\
**Post date:** [May 17, 2014, 8:40am UTC](https://discourse.ats-lang.org/t/gcc-clang-o1-bug/584/5 "2014-05-17T08:40:45Z")

</div>

After off-list discussion (my apologies, but see remark at end), Hongwei  
shared the generated C for this example. Follow the tmpref188 variable. It  
does indeed look like a bug in GCC.

extern atstype\_int  
\_057\_home\_057\_hwxi\_057\_research\_057\_Postiats\_055\_contrib\_057\_git\_057\_projects\_057\_SMALL\_057\_M\_055\_N\_055\_K\_055\_game\_057\_Part1\_057\_game\_board\_056\_dats\_\_board\_dirmax  
(atstype\_ptrk arg0, atstype\_int arg1, atstype\_boxed arg2, atstype\_int arg3,atstype\_int arg4  
) {  
atstype\_int tmpret187 ;  
atstype\_int tmpref188 ;  
;  
;  
atstype\_exnconptr tmp270 ;  
\_\_patsflab\_board\_dirmax: # 5637 “game\_board\_dats.c” (tmpref188 = 0) ;  
ATSLIB\_056\_prelude\_\_ptr\_volatile((&(tmpref188))) ;  
do {  
int flag ;  
atsexnframe\_ptr frame ;  
atsexnframe\_ptr \*framep ;  
frame = alloca(sizeof(atsexnframe\_t)) ;  
framep = my\_atsexnframe\_getref() ;  
my\_atsexnframe\_enter(frame, framep) ;  
flag = \_setjmp (frame-\>  
env) ;  
if (flag==0) {  
loop\_91(arg0, arg1, arg2, (&(tmpref188)), arg3, arg4) ;  
my\_atsexnframe\_leave(framep) ;  
}  
else {  
tmp270 = (_framep)-\>  
exn ;  
my\_atsexnframe\_leave(framep) ;  
do {  
;  
\_\_atstmplab23: if (!(((tmp270)==(void_)(&(  
ATSLIB\_056\_prelude\_\_MatrixSubscriptExn))))) {  
atsruntime\_raise(tmp270) ;  
}  
\_\_atstmplab24: # 5680 “game\_board\_dats.c” ;  
break ;  
}  
while (0) ;  
}  
}  
while(0) ;  
(tmpret187 = ((atstype\_int)tmpref188)) ;  
return (tmpret187) ;

}

About the off-list reply, this Google Group is apparently set up to have  
recipients post their replies “to the author of the message only”. I  
recommend changing the setting to “to the entire group”. On the group  
management page, I believe you can set this in Settings -\> Email options -\>  
Post replies.

---

<div class="post-metadata">

**Author:** ![gmhwxi](https://avatars.discourse-cdn.com/v4/letter/g/67e7ee/32.png) [@gmhwxi](https://discourse.ats-lang.org/u/gmhwxi)\
**Post date:** [May 20, 2014, 2:20am UTC](https://discourse.ats-lang.org/t/gcc-clang-o1-bug/584/6 "2014-05-20T02:20:17Z")

</div>

Here it is.

The file is generated using ‘gcc -E’.

The function of interest is the one whose name contains ‘dirmax’.

If you remove the call to ‘ptr\_volatile’, then ‘gcc -O1’ may generate buggy  
code.

My _guess_ is that the cause of the problem is related to the use of  
longjmp/setjmp in the code.

Rich West showed me a bug of gcc the other day involving longjmp/setjmp.  
There might be a relation  
between these two bugs.On Mon, May 19, 2014 at 2:03 AM, Ian Denhardt [i...@zenhack.net](mailto:i...@zenhack.net) wrote:

> Would it be possible for you (or Hongwei) to attach the generated C source  
> as a  
> separate file? I’d like to have a look at this, but it’s come through a bit  
> mangled in the email.
> 
> -Ian
> 
> Quoting Sean Leather (2014-05-17 04:40:45)
> 
> > …  
> > After off-list discussion (my apologies, but see remark at end),  
> > Hongwei shared the generated C for this example. Follow  
> > the tmpref188 variable. It does indeed look like a bug in GCC.  
> > extern atstype\_int
> 
> \_057\_home\_057\_hwxi\_057\_research\_057\_Postiats\_055\_contrib\_057\_git\_057\_pr
> 
> > 
> 
> ojects\_057\_SMALL\_057\_M\_055\_N\_055\_K\_055\_game\_057\_Part1\_057\_game\_board\_05
> 
> > 6\_dats\_\_board\_dirmax(atstype\_ptrk arg0, atstype\_int arg1,  
> > atstype\_boxed  
> > arg2, atstype\_int arg3, atstype\_int arg4) {  
> > atstype\_int tmpret187 ;  
> > atstype\_int tmpref188 ;  
> > ;  
> > ;  
> > atstype\_exnconptr tmp270 ;  
> > \_\_patsflab\_board\_dirmax: # 5637 “game\_board\_dats.c” (tmpref188 =
> 
> 1. 
> 
> > ;  
> > ATSLIB\_056\_prelude\_\_ptr\_volatile((&(tmpref188))) ;  
> > do {  
> > int flag ;  
> > atsexnframe\_ptr frame ;  
> > atsexnframe\_ptr \*framep ;  
> > frame = alloca(sizeof(atsexnframe\_t)) ;  
> > framep = my\_atsexnframe\_getref() ;  
> > my\_atsexnframe\_enter(frame, framep) ;  
> > flag = \_setjmp (frame-\>  
> > env) ;  
> > if (flag==0) {  
> > loop\_91(arg0, arg1, arg2, (&(tmpref188)), arg3, arg4) ;  
> > my\_atsexnframe\_leave(framep) ;  
> > }  
> > else {  
> > tmp270 = (_framep)-\>  
> > exn ;  
> > my\_atsexnframe\_leave(framep) ;  
> > do {  
> > ;  
> > \_\_atstmplab23: if  
> > (!(((tmp270)==(void_)(&(ATSLIB\_056\_prelude\_\_MatrixSubscriptExn))))) {  
> > atsruntime\_raise(tmp270) ;  
> > }  
> > \_\_atstmplab24: # 5680 “game\_board\_dats.c” ;  
> > break ;  
> > }  
> > while (0) ;  
> > }  
> > }  
> > while(0) ;  
> > (tmpret187 = ((atstype\_int)tmpref188)) ;  
> > return (tmpret187) ;  
> > }  
> > About the off-list reply, this Google Group is apparently set up to  
> > have recipients post their replies �to the author of the message  
> > only�.  
> > I recommend changing the setting to �to the entire group�. On the  
> > group  
> > management page, I believe you can set this in Settings → Email  
> > options → Post replies.
> > 
> > –  
> > You received this message because you are subscribed to the Google  
> > Groups “ats-lang-users” group.  
> > To unsubscribe from this group and stop receiving emails from it, send  
> > an email to [1]ats-lang-user…@googlegroups.com.  
> > To post to this group, send email to  
> > [2]ats-lan…@googlegroups.com.  
> > To view this discussion on the web visit  
> > [3]  
> > [https://groups.google.com/d/msgid/ats-lang-users/2f01e82f-bb89-4999-](https://groups.google.com/d/msgid/ats-lang-users/2f01e82f-bb89-4999-)  
> > a5ff-8095b902f82b%[40googlegroups.com](http://40googlegroups.com).
> > 
> > References
> > 
> > 1. [mailto:ats-lang-user...@googlegroups.com](mailto:ats-lang-user...@googlegroups.com)
> > 2. [mailto:ats-lan...@googlegroups.com](mailto:ats-lan...@googlegroups.com)
> > 3.
> 
> [https://groups.google.com/d/msgid/ats-lang-users/2f01e82f-bb89-4999-a5ff-8095b902f82b%40googlegroups.com?utm\_medium=email&utm\_source=footer](https://groups.google.com/d/msgid/ats-lang-users/2f01e82f-bb89-4999-a5ff-8095b902f82b%40googlegroups.com?utm_medium=email&utm_source=footer)

[game\_board\_dats.c](https://us1.discourse-cdn.com/flex019/uploads/ats_lang/original/1X/1fc5b05229923efc26173e20e9c9911ef66a4ec1.c) (238 KB)
