<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Compilers on onur.one</title><link>https://www.onur.one/tags/compilers/</link><description>Recent content in Compilers on onur.one</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 27 Jul 2026 00:00:00 +0300</lastBuildDate><atom:link href="https://www.onur.one/tags/compilers/index.xml" rel="self" type="application/rss+xml"/><item><title>When a Loop Becomes an Integer Problem: Presburger Reasoning in MLIR Affine</title><link>https://www.onur.one/posts/presburger-affine-mlir/</link><pubDate>Mon, 27 Jul 2026 00:00:00 +0300</pubDate><guid>https://www.onur.one/posts/presburger-affine-mlir/</guid><description>&lt;p&gt;I started with a small compiler question: can this loop run in parallel?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-mlir" data-lang="mlir"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;affine.for &lt;span style="color:#8be9fd;font-style:italic"&gt;%i&lt;/span&gt; = &lt;span style="color:#bd93f9"&gt;0&lt;/span&gt; to &lt;span style="color:#8be9fd;font-style:italic"&gt;%N&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#8be9fd;font-style:italic"&gt;%x&lt;/span&gt; = affine.load &lt;span style="color:#8be9fd;font-style:italic"&gt;%A&lt;/span&gt;[&lt;span style="color:#bd93f9"&gt;2&lt;/span&gt; * &lt;span style="color:#8be9fd;font-style:italic"&gt;%i&lt;/span&gt;] : &lt;span style="color:#8be9fd"&gt;memref&lt;/span&gt;&amp;lt;&lt;span style="color:#bd93f9"&gt;?x&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;f32&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; affine.store &lt;span style="color:#8be9fd;font-style:italic"&gt;%x&lt;/span&gt;, &lt;span style="color:#8be9fd;font-style:italic"&gt;%A&lt;/span&gt;[&lt;span style="color:#bd93f9"&gt;2&lt;/span&gt; * &lt;span style="color:#8be9fd;font-style:italic"&gt;%i&lt;/span&gt; + &lt;span style="color:#bd93f9"&gt;1&lt;/span&gt;] : &lt;span style="color:#8be9fd"&gt;memref&lt;/span&gt;&amp;lt;&lt;span style="color:#bd93f9"&gt;?x&lt;/span&gt;&lt;span style="color:#ff79c6"&gt;f32&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Parallelizing it may change the order in which its memory accesses happen, so
the compiler needs to check whether one iteration depends on another. Both
accesses use the same memref and one of them writes, which makes the question
worth asking.&lt;/p&gt;
&lt;p&gt;Assume &lt;code&gt;%A&lt;/code&gt; has room for &lt;span class="katex"&gt;&lt;math xmlns="http://www.w3.org/1998/Math/MathML"&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding="application/x-tex"&gt;2N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt; elements. Every iteration reads an even address
and writes the following odd address. By inspection, different iterations never
touch the same element. What made me curious was how MLIR could reach that
answer from the Affine IR. Along the way, loop syntax turns into matrix rows,
floor division creates a hidden integer witness, and a parallelization question
becomes a question about whether an integer set is empty. This post is about
that path.&lt;/p&gt;</description></item></channel></rss>