3 ms·
In C, I'm pretty confident the loop is defined by the standard to terminate. Also I did take the excuse to plug it (the optimized llvm ir) into Alive: https:/
by gfaster 10mo ago
In C, I'm pretty confident the loop is defined by the standard to terminate.
Also I did take the excuse to plug it (the optimized llvm ir) into Alive:
https://alive2.llvm.org/ce/#g:!((g:!((g:!((h:codeEditor,i:(fontScale:14,j:1,lang:llvm,selection:(endColumn:8,endLineNumber:1,positionColumn:8,positionLineNumber:1,selectionStartColumn:8,selectionStartLineNumber:1,startColumn:8,startLineNumber:1),source:'define+i32+@src(i32+noundef+%25x,+i32+noundef+%25y)+%7B%0Aentry:%0A++br+label+%25do.body%0A%0Ado.body:%0A++%25y.addr.0+%3D+phi+i32+%5B+%25y,+%25entry+%5D,+%5B+%25xor,+%25do.body+%5D%0A++%25x.addr.0+%3D+phi+i32+%5B+%25x,+%25entry+%5D,+%5B+%25shl,+%25do.body+%5D%0A++%25and+%3D+and+i32+%25x.addr.0,+%25y.addr.0%0A++%25xor+%3D+xor+i32+%25x.addr.0,+%25y.addr.0%0A++%25shl+%3D+shl+i32+%25and,+1%0A++%25tobool.not+%3D+icmp+eq+i32+%25and,+0%0A++br+i1+%25tobool.not,+label+%25do.end,+label+%25do.body%0A%0Ado.end:%0A++ret+i32+%25xor%0A%7D%0A%0Adefine+i32+@tgt(i32+noundef+%25x,+i32+noundef+%25y)+%7B%0A++++%25add+%3D+add+i32+%25x,+%25y%0A++++ret+i32+%25add%0A%7D'),l:'5',n:'0',o:'LLVM+IR+source+%231',t:'0')),k:49.32378679395386,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:alive,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'1',trim:'1'),fontScale:14,j:1,lang:llvm,libs:!(),options:'',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'alive-tv+(Editor+%231,+Compiler+%231)+LLVM+IR',t:'0')),k:50.67621320604614,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4 https://alive2.llvm.org/ce/#g:!((g:!((g:!((h:codeEditor,i:(f...
- dzaima 10mo agoAlive2 does not handle loops; don't know what exactly it does by default, but changing the `shl i32 %and, 1` to `shl i32 %and, 2` has it still report the transformation as valid. You can add `--src-unroll=2` for it to check up to two loop iterations, which does catch such an error (and does still report the original as valid), but of course that's quite limited. (maybe the default is like `--src-unroll=1`?)
- gfaster 10mo agoOh wow nice catch - I was not at all familiar with the limitations. I would've hoped for a warning there, but I suppose it is a research project. I was able to get it working with unrolling and narrower integers: https://alive2.llvm.org/ce/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAM1QDsCBlZAQwBtMQBGAFlICsupVs1qhWrAG4BbUgGdM7ZATx1KmWugDCqVgFcptLgFZS69ABk8tTADl9AI0zFjpAA6pZhFbW16DL909lOktrOylHZ04TeUVg2gYCZmICX31DaLkFTCVvROSCUNsHJxdZJJS0/0zygqLwyOMASjlUXWJkDgByLCorTABqPE4ANgGAAVkOiGGx2jaNTCoBgFIAJiMAD1Ih0YH53UXl9aMATybVgHYAIRWABgBBdQJiU5B7h4GB%2B2IB4UdWKsNuhUAA6ewYU4fD4g8GQ96PL4nU6g5jodDEUF3VYAZgAIgNXAg8LsxisjNcgWcdidnq9VkY8TSKVTNiQacCwRD0KcGXiPkiNptUejMdiVvjCcTSQzKSdtlS6bzyUzZVTZAhWByjLDucrGQKqSJ0LiCcaZfKRRisdqUWjrXdDfKSKaBmzfrNWVaxbbvVinRsNYCJQSgxaNsadpwA0YiBCdKD5gRXXhkFJXANMABHcNGSMDR2I74ezhUuOoBNJnb/BRU2FmavMAF1rmQ6GPesaBGfAbETDJz3O4jQy78x4wpb9GXjAjAAgzPYHI6snaepe9KnnK63IuCvPo1323MK5GGr59gd7E72kd4rotVggLpGLqkQxdO6v1BP8zmABqACyAwAJIAEoDLIbQdIM6w4pwr4EE%2Bn5NC0ADWIDcAAnKCRhYZwmGcPhRiYSMmFrLwj5dNwr7vp%2BpDfl0r6yCAdykIhH73qQcCwEgaDpng7BkBQEB8a4AmlGweASJgpB9KwBBOMxED2Ehr72FYyRvF08GkHxUjPAA8rQrBaXRWBSCIwDsKppD4H2uTScxHGmJsOS6ApT46VYCmUXRrB4D8mnaFgnkIcQeBSKFLQ0PQTBsBwPD8IIwiiCA4jSEIAXMZALSoK48ROQAtIVUzIIVhzEDorAhjiaxMdkuSqBAZhVBkpgaPUJRRG4HheHQrWCIEfW0J1ESlJwWRxHkFSpDo6SCLEOTxPkKSjY0E21JUc3VHIM1reNLSQe0nRcA%2BT4vm%2BNkMZJ0mFQQEgDBAuCEC6sETQM2j8YJQJwRcv6ASBoEIapKGkOhRh3KC3AQwAHHcMNw9wdw4nclwjBRT7UZdzkMUxLFsSDZ1dHV2N0bjBMcaD0nEJ4qjcEAA%3D https://alive2.llvm.org/ce/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF...
- thaumasiotes 10mo ago> In C, I'm pretty confident the loop is defined by the standard to terminate. Huh? What's that supposed to mean?
- gfaster 10mo agoThat it is Undefined Behavior for a loop with a non-constant conditional and that doesn't cause side effects in its body to not terminate. For example, you can use this make the compiler "prove" the Collatz Conjecture: https://gcc.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:___c,selection:(endColumn:4,endLineNumber:1,positionColumn:4,positionLineNumber:1,selectionStartColumn:4,selectionStartLineNumber:1,startColumn:4,startLineNumber:1),source:'void+%0Acollatz(long+n)%0A%7B%0A++++while+(n+!!%3D+1)+%7B%0A++++++++if+(n+%25+2+%3D%3D+0)+%7B%0A++++++++++++n+/%3D+2%3B%0A++++++++%7D+else+%7B%0A++++++++++++n+%3D+n+*+3+%2B+1%3B%0A++++++++%7D%0A++++%7D%0A++++return%3B%0A%7D'),l:'5',n:'0',o:'C+source+%231',t:'0')),k:36.16150836001423,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:cclang2110,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:___c,libs:!(),options:'-O3',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+21.1.0+(Editor+%231)',t:'0')),header:(),k:63.838491639985776,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4 https://gcc.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(file...